/* ------------------------------------ * gap_image_merge_to_specified_layer * ------------------------------------ * remove all other layers from the image except the specified layer_id * (by removing other layers, make ref_layer_id visible and perform merging) */ gint32 gap_image_merge_to_specified_layer(gint32 ref_layer_id, GimpMergeType mergemode) { gint32 l_image_id; l_image_id = gimp_item_get_image(ref_layer_id); if(l_image_id >= 0) { gint32 l_idx; gint l_nlayers; gint32 *l_layers_list; l_layers_list = gimp_image_get_layers(l_image_id, &l_nlayers); if(l_layers_list != NULL) { for(l_idx = 0; l_idx < l_nlayers; l_idx++) { if (l_layers_list[l_idx] == ref_layer_id) { gimp_item_set_visible(l_layers_list[l_idx], TRUE); } else { gimp_image_remove_layer(l_image_id, l_layers_list[l_idx]); } } g_free (l_layers_list); return (gap_image_merge_visible_layers(l_image_id, mergemode)); } } return (-1); } /* end gap_image_merge_to_specified_layer */
void gap_image_prevent_empty_image(gint32 image_id) { GimpImageBaseType l_type; guint l_width, l_height; gint32 l_layer_id; gint l_nlayers; gint32 *l_layers_list; l_layers_list = gimp_image_get_layers(image_id, &l_nlayers); if(l_layers_list != NULL) { g_free (l_layers_list); } else l_nlayers = 0; if(l_nlayers == 0) { /* the resulting image has no layer, add a transparent dummy layer */ /* get info about the image */ l_width = gimp_image_width(image_id); l_height = gimp_image_height(image_id); l_type = gimp_image_base_type(image_id); l_type = (l_type * 2); /* convert from GimpImageBaseType to GimpImageType */ /* add a transparent dummy layer */ l_layer_id = gimp_layer_new(image_id, "dummy", l_width, l_height, l_type, 0.0, /* Opacity full transparent */ 0); /* NORMAL */ gimp_image_insert_layer(image_id, l_layer_id, 0, 0); } } /* end gap_image_prevent_empty_image */
static void run (const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[2]; GimpPDBStatusType status = GIMP_PDB_EXECUTION_ERROR; GimpRunMode run_mode; gint image_id, layer_num; run_mode = param[0].data.d_int32; image_id = param[1].data.d_int32; INIT_I18N (); *nreturn_vals = 1; *return_vals = values; values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; switch ( run_mode ) { case GIMP_RUN_INTERACTIVE: gimp_image_get_layers (image_id, &layer_num); if (layer_num < 2) { *nreturn_vals = 2; values[1].type = GIMP_PDB_STRING; values[1].data.d_string = _("There are not enough layers to align."); return; } gimp_get_data (PLUG_IN_PROC, &VALS); VALS.grid_size = MAX (VALS.grid_size, 1); if (! align_layers_dialog ()) return; break; case GIMP_RUN_NONINTERACTIVE: break; case GIMP_RUN_WITH_LAST_VALS: gimp_get_data (PLUG_IN_PROC, &VALS); break; } status = align_layers (image_id); if (run_mode != GIMP_RUN_NONINTERACTIVE) gimp_displays_flush (); if (run_mode == GIMP_RUN_INTERACTIVE && status == GIMP_PDB_SUCCESS) gimp_set_data (PLUG_IN_PROC, &VALS, sizeof (ValueType)); values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; }
gint count_extra_layers (gint32 image_ID) { gint32 *layer_array; gint num_layers; layer_array = gimp_image_get_layers (image_ID, &num_layers); return num_layers - 1; }
GimpLayer * gimp_image_flatten (GimpImage *image, GimpContext *context, GError **error) { GList *list; GSList *merge_list = NULL; GimpLayer *layer; g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL); g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); for (list = gimp_image_get_layer_iter (image); list; list = g_list_next (list)) { layer = list->data; if (gimp_layer_is_floating_sel (layer)) continue; if (gimp_item_get_visible (GIMP_ITEM (layer))) merge_list = g_slist_append (merge_list, layer); } if (merge_list) { gimp_set_busy (image->gimp); gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_LAYERS_MERGE, C_("undo-type", "Flatten Image")); /* if there's a floating selection, anchor it */ if (gimp_image_get_floating_selection (image)) floating_sel_anchor (gimp_image_get_floating_selection (image)); layer = gimp_image_merge_layers (image, gimp_image_get_layers (image), merge_list, context, GIMP_FLATTEN_IMAGE); g_slist_free (merge_list); gimp_image_alpha_changed (image); gimp_image_undo_group_end (image); gimp_unset_busy (image->gimp); return layer; } g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, _("Cannot flatten an image without any visible layer.")); return NULL; }
gint webx_indexed_target_get_image (WebxIndexedTarget *indexed, WebxTargetInput *input, gint *layer) { gint tmp_image; gint tmp_layer; gint *layers; gint num_layers; gchar *custom_palette; gint num_colors; gboolean converted; g_return_val_if_fail (WEBX_IS_INDEXED_TARGET (indexed), -1); if (indexed->palette_type == GIMP_REUSE_PALETTE) { *layer = input->indexed_layer; return input->indexed_image; } custom_palette = indexed->custom_palette; if (! custom_palette) custom_palette = ""; tmp_image = input->rgb_image; tmp_layer = input->rgb_layer; num_colors = indexed->num_colors; if (num_colors == 256 && gimp_drawable_has_alpha (tmp_layer)) num_colors = 255; tmp_image = gimp_image_duplicate (tmp_image); converted = gimp_image_convert_indexed (tmp_image, indexed->dither_type, indexed->palette_type, num_colors, indexed->alpha_dither, indexed->remove_unused, custom_palette); if (! converted) { gimp_image_delete (tmp_image); *layer = -1; return -1; } layers = gimp_image_get_layers (tmp_image, &num_layers); g_assert (num_layers == 1); tmp_layer = layers[0]; indexed->image = tmp_image; indexed->layer = tmp_layer; *layer= tmp_layer; return tmp_image; }
static gboolean apply_userdef(userdef_settings settings, image_output out) { gboolean success = TRUE; int param_i; GimpParamDef param_info; gboolean saving_function = (strstr(settings->procedure, "-save") != NULL); int single_drawable = gimp_image_merge_visible_layers(out->image_id, GIMP_CLIP_TO_IMAGE); for (param_i = 0; param_i < settings->num_params; param_i++) { switch((settings->params[param_i]).type) { case GIMP_PDB_IMAGE: (settings->params[param_i]).data.d_image = out->image_id; break; case GIMP_PDB_DRAWABLE: case GIMP_PDB_ITEM: (settings->params[param_i]).data.d_drawable = single_drawable; break; case GIMP_PDB_STRING: if (saving_function) { param_info = pdb_proc_get_param_info(settings->procedure, param_i); if (strcmp(param_info.name, "filename") == 0) { (settings->params[param_i]).data.d_string = g_strdup(out->filepath); } else if (strcmp(param_info.name, "raw-filename") == 0) { (settings->params[param_i]).data.d_string = g_strdup(out->filename); } } break; default: break; } } gint nreturn_vals; GimpParam *return_vals = gimp_run_procedure2( settings->procedure, &nreturn_vals, settings->num_params, settings->params ); gimp_image_merge_visible_layers(out->image_id, GIMP_CLIP_TO_IMAGE); g_free(out->drawable_ids); out->drawable_ids = gimp_image_get_layers(out->image_id, &out->drawable_count); return success; }
/* ----------------------------- * gap_image_get_the_layer_below * ----------------------------- * returns the id of the layer below the specified layerId * * returns -1 in case there is no layer below the specified layerId * Note that -1 is alse returned * a) in case the specified layerId is not a valid layer (or not attached to an image) * b) in case the specified layerId is on bottom of a layergroup * c) in case the specified layerId is on bottom of the toplevel layerstack */ gint32 gap_image_get_the_layer_below(gint32 layerId) { gint32 lowerLayerId; gint32 l_parent_id; gint l_nlayers; gint32 *l_layers_list; gint l_ii; lowerLayerId = -1; l_parent_id = 0; if (layerId >= 0) { l_parent_id = gimp_item_get_parent(layerId); } if (l_parent_id > 0) { l_layers_list = gimp_item_get_children(l_parent_id, &l_nlayers); } else { /* use toplevel layers list of the image */ l_layers_list = gimp_image_get_layers(gimp_item_get_image(layerId), &l_nlayers); } if (l_layers_list == NULL) { return (-1); } for(l_ii = 0; l_ii < l_nlayers; l_ii++) { if (l_layers_list[l_ii] == layerId) { gint l_pos_below = l_ii + 1; if (l_pos_below < l_nlayers) { lowerLayerId = l_layers_list[l_pos_below]; break; } } } g_free(l_layers_list); return (lowerLayerId); } /* end gap_image_get_the_layer_below */
static void export_convert_indexed (gint32 image_ID, gint32 *drawable_ID) { gint32 nlayers; /* check alpha */ g_free (gimp_image_get_layers (image_ID, &nlayers)); if (nlayers > 1 || gimp_drawable_has_alpha (*drawable_ID)) gimp_image_convert_indexed (image_ID, GIMP_NO_DITHER, GIMP_MAKE_PALETTE, 255, FALSE, FALSE, ""); else gimp_image_convert_indexed (image_ID, GIMP_NO_DITHER, GIMP_MAKE_PALETTE, 256, FALSE, FALSE, ""); }
/* * Return the bottom layer. */ static gint align_layers_find_background (gint32 image_id) { gint *layers; gint layers_num; gint background; gboolean found = FALSE; layers = gimp_image_get_layers (image_id, &layers_num); background = align_layers_find_last_layer (layers, layers_num, &found); g_free (layers); return background; }
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); }
static void lcms_image_transform_rgb (gint32 image, cmsHPROFILE src_profile, cmsHPROFILE dest_profile, GimpColorRenderingIntent intent, gboolean bpc) { gint *layers; gint num_layers; layers = gimp_image_get_layers (image, &num_layers); lcms_layers_transform_rgb (layers, num_layers, src_profile, dest_profile, intent, bpc); g_free (layers); }
static void export_apply_masks (gint32 image_ID, gint *drawable_ID) { gint32 n_layers; gint32 *layers; gint i; layers = gimp_image_get_layers (image_ID, &n_layers); for (i = 0; i < n_layers; i++) { if (gimp_layer_get_mask (layers[i]) != -1) gimp_layer_remove_mask (layers[i], GIMP_MASK_APPLY); } 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_ids = gimp_image_get_layers(imageout->image_id, &imageout->drawable_count); // get all drawables g_print("Total drawables count: %d\n", imageout->drawable_count); // 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); } }
/* ------------------------------------ * gap_image_get_any_layer * ------------------------------------ * return the id of the active layer * or the id of the first layer found in the image if there is no active layer * or -1 if the image has no layer at all. */ gint32 gap_image_get_any_layer(gint32 image_id) { gint32 l_layer_id; gint l_nlayers; gint32 *l_layers_list; l_layer_id = gimp_image_get_active_layer(image_id); if(l_layer_id < 0) { l_layers_list = gimp_image_get_layers(image_id, &l_nlayers); if(l_layers_list != NULL) { l_layer_id = l_layers_list[0]; g_free (l_layers_list); } } return (l_layer_id); } /* end gap_image_get_any_layer */
void removeAllLayersExceptMain(void) { gint *pnLayers = NULL; gint numLayers = 0 ; gint nIndex = 0 ; gimp_image_set_active_layer(local_vals.image_ID, drawableBeginActiveLayer); pnLayers = gimp_image_get_layers(local_vals.image_ID, &numLayers); for (nIndex=0;nIndex< numLayers;nIndex++) { if (pnLayers[nIndex] != drawableBeginActiveLayer) { if (gimp_layer_is_floating_sel(pnLayers[nIndex])) { gimp_floating_sel_remove(pnLayers[nIndex]); } else { gimp_image_remove_layer(local_vals.image_ID, pnLayers[nIndex]); } } } gimp_drawable_set_visible(drawableBeginActiveLayer, TRUE); }
/* * Return a contiguous array of all visible layers */ static gint * align_layers_spread_image (gint32 image_id, gint *layer_num) { gint *layers; gint *layers_array; gint layer_num_loc; layers = gimp_image_get_layers (image_id, &layer_num_loc); *layer_num = align_layers_count_visibles_layers (layers, layer_num_loc); layers_array = g_malloc (sizeof (gint) * *layer_num); align_layers_spread_visibles_layers (layers, layer_num_loc, layers_array); g_free (layers); return layers_array; }
/* --------------------------------------- * gap_image_remove_invisble_layers * --------------------------------------- */ void gap_image_remove_invisble_layers(gint32 image_id) { gint l_nlayers; gint32 *l_layers_list; l_layers_list = gimp_image_get_layers(image_id, &l_nlayers); if(l_layers_list != NULL) { int ii; for(ii=0; ii < l_nlayers; ii++) { if (gimp_item_get_visible(l_layers_list[ii]) != TRUE) { gimp_image_remove_layer(image_id, l_layers_list[ii]); } } g_free (l_layers_list); } } /* end gap_image_remove_invisble_layers */
static void p_delta_drawable(gint32 *val, gint32 val_from, gint32 val_to, gint32 total_steps, gdouble current_step) { gint l_nlayers; gint32 *l_layers_list; gint32 l_tmp_image_id; gint l_idx, l_idx_from, l_idx_to; if((val_from < 0) || (val_to < 0)) { return; } l_tmp_image_id = gimp_drawable_image_id(val_from); /* check if from and to values are both valid drawables within the same image */ if ((l_tmp_image_id > 0) && (l_tmp_image_id = gimp_drawable_image_id(val_to))) { l_idx_from = -1; l_idx_to = -1; /* check the layerstack index of from and to drawable */ l_layers_list = gimp_image_get_layers(l_tmp_image_id, &l_nlayers); for (l_idx = l_nlayers -1; l_idx >= 0; l_idx--) { if( l_layers_list[l_idx] == val_from ) l_idx_from = l_idx; if( l_layers_list[l_idx] == val_to ) l_idx_to = l_idx; if((l_idx_from != -1) && (l_idx_to != -1)) { /* OK found both index values, iterate the index (proceed to next layer) */ p_delta_gint(&l_idx, l_idx_from, l_idx_to, total_steps, current_step); *val = l_layers_list[l_idx]; break; } } g_free (l_layers_list); } }
/* --------------------------------------- * gap_image_limit_layers * --------------------------------------- * keepTopLayers number of layers to keep on top of the layerstack (Foreground). * keepBgLayers number of layers to keep on bottom of the layerstack (Background). * * Note that gimp-2.7 or later versions supports layer groups. * this procedure does only check for toplevel layers * and ignores layers that are nested in groups. * A top level group counts as one single layer * no matter how many layers und subgroups are in the toplevel group. * */ void gap_image_limit_layers(gint32 image_id, gint keepTopLayers, gint keepBgLayers) { gint l_nlayers; gint32 *l_layers_list; l_layers_list = gimp_image_get_layers(image_id, &l_nlayers); if(l_layers_list != NULL) { int ii; for(ii=0; ii < l_nlayers; ii++) { if ((ii >= keepTopLayers) && ((l_nlayers -ii) > keepBgLayers)) { gimp_image_remove_layer(image_id, l_layers_list[ii]); } } g_free (l_layers_list); } } /* end gap_image_limit_layers */
static void gimp_image_duplicate_floating_sel (GimpImage *image, GimpImage *new_image) { GimpLayer *floating_sel; GimpDrawable *floating_sel_drawable; GList *floating_sel_path; GimpItemStack *new_item_stack; GimpLayer *new_floating_sel; GimpDrawable *new_floating_sel_drawable; floating_sel = gimp_image_get_floating_selection (image); if (! floating_sel) return; floating_sel_drawable = gimp_layer_get_floating_sel_drawable (floating_sel); if (GIMP_IS_LAYER_MASK (floating_sel_drawable)) { GimpLayer *layer; layer = gimp_layer_mask_get_layer (GIMP_LAYER_MASK (floating_sel_drawable)); floating_sel_path = gimp_item_get_path (GIMP_ITEM (layer)); new_item_stack = GIMP_ITEM_STACK (gimp_image_get_layers (new_image)); } else { floating_sel_path = gimp_item_get_path (GIMP_ITEM (floating_sel_drawable)); if (GIMP_IS_LAYER (floating_sel_drawable)) new_item_stack = GIMP_ITEM_STACK (gimp_image_get_layers (new_image)); else new_item_stack = GIMP_ITEM_STACK (gimp_image_get_channels (new_image)); } /* adjust path[0] for the floating layer missing in new_image */ floating_sel_path->data = GUINT_TO_POINTER (GPOINTER_TO_UINT (floating_sel_path->data) - 1); if (GIMP_IS_LAYER (floating_sel_drawable)) { new_floating_sel = GIMP_LAYER (gimp_image_duplicate_item (GIMP_ITEM (floating_sel), new_image)); } else { /* can't use gimp_item_convert() for floating selections of channels * or layer masks because they maybe don't have a normal layer's type */ new_floating_sel = GIMP_LAYER (gimp_item_duplicate (GIMP_ITEM (floating_sel), G_TYPE_FROM_INSTANCE (floating_sel))); gimp_item_set_image (GIMP_ITEM (new_floating_sel), new_image); gimp_object_set_name (GIMP_OBJECT (new_floating_sel), gimp_object_get_name (floating_sel)); } /* Make sure the copied layer doesn't say: "<old layer> copy" */ gimp_object_set_name (GIMP_OBJECT (new_floating_sel), gimp_object_get_name (floating_sel)); new_floating_sel_drawable = GIMP_DRAWABLE (gimp_item_stack_get_item_by_path (new_item_stack, floating_sel_path)); if (GIMP_IS_LAYER_MASK (floating_sel_drawable)) new_floating_sel_drawable = GIMP_DRAWABLE (gimp_layer_get_mask (GIMP_LAYER (new_floating_sel_drawable))); floating_sel_attach (new_floating_sel, new_floating_sel_drawable); g_list_free (floating_sel_path); }
static gboolean apply_watermark(watermark_settings settings, image_output out) { gboolean success = TRUE; gint32 layerId; gdouble posX, posY; gint wmwidth, wmheight, wmasc, wmdesc; if (settings->mode) { if (strlen(settings->text) == 0) { return TRUE; } GimpRGB old_foreground, new_foreground; gimp_context_get_foreground(&old_foreground); gimp_rgb_parse_hex (&new_foreground, gdk_color_to_string(&(settings->color)), strlen(gdk_color_to_string(&(settings->color)))); gimp_context_set_foreground(&new_foreground); gimp_text_get_extents_fontname( settings->text, pango_font_description_get_size(settings->font) / PANGO_SCALE, GIMP_PIXELS, pango_font_description_get_family(settings->font), &wmwidth, &wmheight, &wmasc, &wmdesc ); if (settings->position == WM_POS_TL) { posX = 10; posY = 5; } else if (settings->position == WM_POS_TC) { posX = (gimp_image_width(out->image_id) / 2) - (wmwidth / 2); posY = 5; } else if (settings->position == WM_POS_TR) { posX = gimp_image_width(out->image_id) - wmwidth - 10; posY = 5; } else if (settings->position == WM_POS_BL) { posX = 10; posY = gimp_image_height(out->image_id) - wmheight - 5; } else if (settings->position == WM_POS_BC) { posX = (gimp_image_width(out->image_id) / 2) - (wmwidth / 2); posY = gimp_image_height(out->image_id) - wmheight - 5; } else if (settings->position == WM_POS_BR) { posX = gimp_image_width(out->image_id) - wmwidth - 10; posY = gimp_image_height(out->image_id) - wmheight - 5; } else if (settings->position == WM_POS_CL) { posX = 10; posY = (gimp_image_height(out->image_id) / 2) - (wmheight / 2); } else if (settings->position == WM_POS_CR) { posX = gimp_image_width(out->image_id) - wmwidth - 10; posY = (gimp_image_height(out->image_id) / 2) - (wmheight / 2); } else { posX = (gimp_image_width(out->image_id) / 2) - (wmwidth / 2); posY = (gimp_image_height(out->image_id) / 2) - (wmheight / 2); } layerId = gimp_text_fontname( out->image_id, -1, posX, posY, settings->text, -1, TRUE, pango_font_description_get_size(settings->font) / PANGO_SCALE, GIMP_PIXELS, pango_font_description_get_family(settings->font) ); gimp_context_set_foreground(&old_foreground); gimp_layer_set_opacity(layerId, settings->opacity); } else { if (!g_file_test(settings->image_file, G_FILE_TEST_IS_REGULAR)) {//((access(settings->image_file, R_OK) == -1)) { // error, can't access image file return TRUE; } layerId = gimp_file_load_layer( GIMP_RUN_NONINTERACTIVE, out->image_id, settings->image_file ); gimp_layer_set_opacity(layerId, settings->opacity); wmwidth = gimp_drawable_width(layerId); wmheight = gimp_drawable_height(layerId); #if USE_API26 gimp_image_add_layer( out->image_id, layerId, 0 ); #else // starting from 2.8, gimp_image_add_layer is deprecated. // use gimp_image_insert_layer instead gimp_image_insert_layer( out->image_id, layerId, 0, 0 ); #endif if (settings->position == WM_POS_TL) { posX = 10; posY = 10; } else if (settings->position == WM_POS_TC) { posX = (gimp_image_width(out->image_id) / 2) - (wmwidth / 2); posY = 10; } else if (settings->position == WM_POS_TR) { posX = gimp_image_width(out->image_id) - wmwidth - 10; posY = 10; } else if (settings->position == WM_POS_BL) { posX = 10; posY = gimp_image_height(out->image_id) - wmheight - 10; } else if (settings->position == WM_POS_BC) { posX = (gimp_image_width(out->image_id) / 2) - (wmwidth / 2); posY = gimp_image_height(out->image_id) - wmheight - 10; } else if (settings->position == WM_POS_BR) { posX = gimp_image_width(out->image_id) - wmwidth - 10; posY = gimp_image_height(out->image_id) - wmheight - 10; } else if (settings->position == WM_POS_CL) { posX = 10; posY = (gimp_image_height(out->image_id) / 2) - (wmheight / 2); } else if (settings->position == WM_POS_CR) { posX = gimp_image_width(out->image_id) - wmwidth - 10; posY = (gimp_image_height(out->image_id) / 2) - (wmheight / 2); } else { posX = (gimp_image_width(out->image_id) / 2) - (wmwidth / 2); posY = (gimp_image_height(out->image_id) / 2) - (wmheight / 2); } gimp_layer_set_offsets( layerId, posX, posY ); } // refresh all drawables g_free(out->drawable_ids); out->drawable_ids = gimp_image_get_layers(out->image_id, &out->drawable_count); return success; }
GimpPDBStatusType SaveICNS (const gchar *file_name, gint32 image_ID) { // Horrible awful temporary hack ResourceHeader icnsHeader; ResourceHeader it32Header; ResourceHeader t8mkHeader; guchar *compData, *alphaData; FILE *outfile; guchar *pixels; gint dataSize; if (gimp_image_base_type (image_ID) != GIMP_RGB) { if (! gimp_image_convert_rgb (image_ID)) return GIMP_PDB_EXECUTION_ERROR; } gint *layers; gint nlayers; GimpPixelRgn region; layers = gimp_image_get_layers (image_ID, &nlayers); GimpDrawable *drawable = gimp_drawable_get (layers[0]); pixels = g_new (guchar, 128*128*4); gimp_pixel_rgn_init (®ion, drawable, 0, 0, 128, 128, TRUE, FALSE); gimp_pixel_rgn_get_rect (®ion, pixels, 0, 0, 128, 128); compData = icns_compress (128, 128, pixels, &dataSize); alphaData = icns_get_alpha (128, 128, pixels); it32Header.type = GUINT32_TO_BE ('it32'); it32Header.size = GUINT32_TO_BE (sizeof (ResourceHeader) + dataSize); t8mkHeader.type = GUINT32_TO_BE ('t8mk'); t8mkHeader.size = GUINT32_TO_BE (sizeof (ResourceHeader) + 128*128); icnsHeader.type = GUINT32_TO_BE ('icns'); icnsHeader.size = dataSize + 128*128 + 3 * sizeof (ResourceHeader); outfile = fopen (file_name, "wb"); if (outfile) { fwrite (&icnsHeader, 1, sizeof (ResourceHeader), outfile); fwrite (&it32Header, 1, sizeof (ResourceHeader), outfile); fwrite (compData, 1, dataSize, outfile); fwrite (&t8mkHeader, 1, sizeof (ResourceHeader), outfile); fwrite (alphaData, 1, 128*128, outfile); fclose (outfile); } else { g_warning ("SaveICNS: couldn't open output file"); } g_free (pixels); g_free (compData); g_free (alphaData); return GIMP_PDB_SUCCESS; }
static gboolean webx_pipeline_check_update (WebxPipeline *pipeline) { gint *layers; gint num_layers; gint i; g_return_val_if_fail (WEBX_IS_PIPELINE (pipeline), FALSE); if (pipeline->rgb_image != -1) { gimp_image_delete (pipeline->rgb_image); pipeline->rgb_image = -1; } if (pipeline->indexed_image != -1) { gimp_image_delete (pipeline->indexed_image); pipeline->indexed_image = -1; } if (pipeline->background) { g_object_unref (pipeline->background); pipeline->background = NULL; } pipeline->rgb_image = gimp_image_duplicate (pipeline->user_image); gimp_image_undo_disable (pipeline->rgb_image); pipeline->rgb_layer = gimp_image_merge_visible_layers (pipeline->rgb_image, GIMP_CLIP_TO_IMAGE); /* make sure there is only one layer, where all visible layers were merged */ layers = gimp_image_get_layers (pipeline->rgb_image, &num_layers); for (i = 0; i < num_layers; i++) { if (layers[i] != pipeline->rgb_layer) gimp_image_remove_layer (pipeline->rgb_image, layers[i]); } g_free (layers); /* we don't want layer to be smaller than image */ gimp_layer_resize_to_image_size (pipeline->rgb_layer); gimp_image_scale (pipeline->rgb_image, pipeline->resize_width, pipeline->resize_height); webx_pipeline_create_background (pipeline); pipeline->crop_offsx *= pipeline->crop_scale_x; pipeline->crop_offsy *= pipeline->crop_scale_y; pipeline->crop_width *= pipeline->crop_scale_x; pipeline->crop_height *= pipeline->crop_scale_y; pipeline->crop_scale_x = 1.0; pipeline->crop_scale_y = 1.0; webx_pipeline_crop_clip (pipeline); if (pipeline->crop_width != pipeline->resize_width || pipeline->crop_height != pipeline->resize_height ) { gimp_image_crop (pipeline->rgb_image, pipeline->crop_width, pipeline->crop_height, pipeline->crop_offsx, pipeline->crop_offsy); } if (gimp_drawable_is_indexed (pipeline->rgb_layer)) { pipeline->indexed_image = gimp_image_duplicate (pipeline->rgb_image); gimp_image_undo_disable (pipeline->indexed_image); pipeline->indexed_layer = gimp_image_merge_visible_layers (pipeline->indexed_image, GIMP_CLIP_TO_IMAGE); } else { pipeline->indexed_image = -1; pipeline->indexed_layer = -1; } if ( ! gimp_drawable_is_rgb (pipeline->rgb_layer)) gimp_image_convert_rgb (pipeline->rgb_image); return TRUE; }
void image_actions_update (GimpActionGroup *group, gpointer data) { GimpImage *image = action_data_get_image (data); gboolean is_indexed = FALSE; gboolean is_u8_gamma = FALSE; gboolean aux = FALSE; gboolean lp = FALSE; gboolean sel = FALSE; gboolean groups = FALSE; gboolean profile = FALSE; if (image) { GimpContainer *layers; const gchar *action = NULL; switch (gimp_image_get_base_type (image)) { case GIMP_RGB: action = "image-convert-rgb"; break; case GIMP_GRAY: action = "image-convert-grayscale"; break; case GIMP_INDEXED: action = "image-convert-indexed"; break; } gimp_action_group_set_action_active (group, action, TRUE); switch (gimp_image_get_precision (image)) { case GIMP_PRECISION_U8_LINEAR: action = "image-convert-u8-linear"; break; case GIMP_PRECISION_U8_GAMMA: action = "image-convert-u8-gamma"; break; case GIMP_PRECISION_U16_LINEAR: action = "image-convert-u16-linear"; break; case GIMP_PRECISION_U16_GAMMA: action = "image-convert-u16-gamma"; break; case GIMP_PRECISION_U32_LINEAR: action = "image-convert-u32-linear"; break; case GIMP_PRECISION_U32_GAMMA: action = "image-convert-u32-gamma"; break; case GIMP_PRECISION_HALF_LINEAR: action = "image-convert-half-linear"; break; case GIMP_PRECISION_HALF_GAMMA: action = "image-convert-half-gamma"; break; case GIMP_PRECISION_FLOAT_LINEAR: action = "image-convert-float-linear"; break; case GIMP_PRECISION_FLOAT_GAMMA: action = "image-convert-float-gamma"; break; case GIMP_PRECISION_DOUBLE_LINEAR: action = "image-convert-double-linear"; break; case GIMP_PRECISION_DOUBLE_GAMMA: action = "image-convert-double-gamma"; break; } gimp_action_group_set_action_active (group, action, TRUE); is_indexed = (gimp_image_get_base_type (image) == GIMP_INDEXED); is_u8_gamma = (gimp_image_get_precision (image) == GIMP_PRECISION_U8_GAMMA); aux = (gimp_image_get_active_channel (image) != NULL); lp = ! gimp_image_is_empty (image); sel = ! gimp_channel_is_empty (gimp_image_get_mask (image)); layers = gimp_image_get_layers (image); groups = ! gimp_item_stack_is_flat (GIMP_ITEM_STACK (layers)); profile = (gimp_image_get_icc_parasite (image) != NULL); } #define SET_SENSITIVE(action,condition) \ gimp_action_group_set_action_sensitive (group, action, (condition) != 0) SET_SENSITIVE ("image-convert-rgb", image); SET_SENSITIVE ("image-convert-grayscale", image); SET_SENSITIVE ("image-convert-indexed", image && !groups && is_u8_gamma); SET_SENSITIVE ("image-convert-u8-gamma", image); SET_SENSITIVE ("image-convert-u8-linear", image && !is_indexed); SET_SENSITIVE ("image-convert-u16-gamma", image && !is_indexed); SET_SENSITIVE ("image-convert-u16-linear", image && !is_indexed); SET_SENSITIVE ("image-convert-u32-gamma", image && !is_indexed); SET_SENSITIVE ("image-convert-u32-linear", image && !is_indexed); SET_SENSITIVE ("image-convert-half-gamma", image && !is_indexed); SET_SENSITIVE ("image-convert-half-linear", image && !is_indexed); SET_SENSITIVE ("image-convert-float-gamma", image && !is_indexed); SET_SENSITIVE ("image-convert-float-linear", image && !is_indexed); SET_SENSITIVE ("image-convert-double-gamma", image && !is_indexed); SET_SENSITIVE ("image-convert-double-linear", image && !is_indexed); SET_SENSITIVE ("image-color-profile-assign", image); SET_SENSITIVE ("image-color-profile-convert", image); SET_SENSITIVE ("image-color-profile-discard", image && profile); SET_SENSITIVE ("image-flip-horizontal", image); SET_SENSITIVE ("image-flip-vertical", image); SET_SENSITIVE ("image-rotate-90", image); SET_SENSITIVE ("image-rotate-180", image); SET_SENSITIVE ("image-rotate-270", image); SET_SENSITIVE ("image-resize", image); SET_SENSITIVE ("image-resize-to-layers", image); SET_SENSITIVE ("image-resize-to-selection", image && sel); SET_SENSITIVE ("image-print-size", image); SET_SENSITIVE ("image-scale", image); SET_SENSITIVE ("image-crop-to-selection", image && sel); SET_SENSITIVE ("image-crop-to-content", image); SET_SENSITIVE ("image-duplicate", image); SET_SENSITIVE ("image-merge-layers", image && !aux && lp); SET_SENSITIVE ("image-flatten", image && !aux && lp); SET_SENSITIVE ("image-configure-grid", image); SET_SENSITIVE ("image-properties", image); #undef SET_SENSITIVE }
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 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]; GimpPDBStatusType status = GIMP_PDB_SUCCESS; GimpRunMode run_mode; /* Plug-in variables */ gboolean single_image; gboolean defaults_proc; /* Plug-In variables */ cairo_surface_t *pdf_file; cairo_t *cr; GimpExportCapabilities capabilities; guint32 i = 0; gint32 j = 0; gdouble x_res, y_res; gdouble x_scale, y_scale; gint32 image_id; gboolean exported; GimpImageBaseType type; gint32 temp; gint *layers; gint32 num_of_layers; GimpDrawable *layer; cairo_surface_t *layer_image; gdouble opacity; gint x, y; GimpRGB layer_color; gboolean single_color; gint32 mask_id = -1; GimpDrawable *mask = NULL; cairo_surface_t *mask_image = NULL; FILE *fp; INIT_I18N (); /* Setting mandatory output values */ *nreturn_vals = 1; *return_vals = values; values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; /* Initializing all the settings */ multi_page.image_count = 0; if (! init_vals (name, nparams, param, &single_image, &defaults_proc, &run_mode)) { values[0].data.d_status = GIMP_PDB_CALLING_ERROR; return; } /* Starting the executions */ if (run_mode == GIMP_RUN_INTERACTIVE) { if (single_image) { if (! gui_single ()) { values[0].data.d_status = GIMP_PDB_CANCEL; return; } } else if (! gui_multi ()) { values[0].data.d_status = GIMP_PDB_CANCEL; return; } if (file_name == NULL) { values[0].data.d_status = GIMP_PDB_CALLING_ERROR; gimp_message (_("You must select a file to save!")); return; } } fp = g_fopen (file_name, "wb"); pdf_file = cairo_pdf_surface_create_for_stream (write_func, fp, 1, 1); if (cairo_surface_status (pdf_file) != CAIRO_STATUS_SUCCESS) { char *str = g_strdup_printf (_("An error occured while creating the PDF file:\n" "%s\n" "Make sure you entered a valid filename and that the selected location isn't read only!"), cairo_status_to_string (cairo_surface_status (pdf_file))); gimp_message (str); g_free (str); values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR; return; } cr = cairo_create (pdf_file); capabilities = GIMP_EXPORT_CAN_HANDLE_RGB | GIMP_EXPORT_CAN_HANDLE_ALPHA | GIMP_EXPORT_CAN_HANDLE_GRAY | GIMP_EXPORT_CAN_HANDLE_LAYERS | GIMP_EXPORT_CAN_HANDLE_INDEXED; if (optimize.apply_masks) capabilities |= GIMP_EXPORT_CAN_HANDLE_LAYER_MASKS; for (i = 0; i < multi_page.image_count; i++) { /* Save the state of the surface before any changes, so that settings * from one page won't affect all the others */ cairo_save (cr); image_id = multi_page.images[i]; /* We need the active layer in order to use gimp_image_export */ temp = gimp_image_get_active_drawable (image_id); if (temp == -1) exported = gimp_export_image (&image_id, &temp, NULL, capabilities) == GIMP_EXPORT_EXPORT; else exported = FALSE; type = gimp_image_base_type (image_id); gimp_image_get_resolution (image_id, &x_res, &y_res); x_scale = 72.0 / x_res; y_scale = 72.0 / y_res; cairo_pdf_surface_set_size (pdf_file, gimp_image_width (image_id) * x_scale, gimp_image_height (image_id) * y_scale); /* This way we set how many pixels are there in every inch. * It's very important for PangoCairo */ cairo_surface_set_fallback_resolution (pdf_file, x_res, y_res); /* PDF is usually 72 points per inch. If we have a different resolution, * we will need this to fit our drawings */ cairo_scale (cr, x_scale, y_scale); /* Now, we should loop over the layers of each image */ layers = gimp_image_get_layers (image_id, &num_of_layers); for (j = 0; j < num_of_layers; j++) { layer = gimp_drawable_get (layers [num_of_layers-j-1]); opacity = gimp_layer_get_opacity (layer->drawable_id)/100.0; /* Gimp doesn't display indexed layers with opacity below 50% * And if it's above 50%, it will be rounded to 100% */ if (type == GIMP_INDEXED) { if (opacity <= 0.5) opacity = 0.0; else opacity = 1.0; } if (gimp_item_get_visible (layer->drawable_id) && (! optimize.ignore_hidden || (optimize.ignore_hidden && opacity > 0.0))) { mask_id = gimp_layer_get_mask (layer->drawable_id); if (mask_id != -1) { mask = gimp_drawable_get (mask_id); mask_image = get_drawable_image (mask); } gimp_drawable_offsets (layer->drawable_id, &x, &y); /* For raster layers */ if (!gimp_item_is_text_layer (layer->drawable_id)) { layer_color = get_layer_color (layer, &single_color); cairo_rectangle (cr, x, y, layer->width, layer->height); if (optimize.vectorize && single_color) { cairo_set_source_rgba (cr, layer_color.r, layer_color.g, layer_color.b, layer_color.a * opacity); if (mask_id != -1) cairo_mask_surface (cr, mask_image, x, y); else cairo_fill (cr); } else { cairo_clip (cr); layer_image = get_drawable_image (layer); cairo_set_source_surface (cr, layer_image, x, y); cairo_push_group (cr); cairo_paint_with_alpha (cr, opacity); cairo_pop_group_to_source (cr); if (mask_id != -1) cairo_mask_surface (cr, mask_image, x, y); else cairo_paint (cr); cairo_reset_clip (cr); cairo_surface_destroy (layer_image); } } /* For text layers */ else { drawText (layer, opacity, cr, x_res, y_res); } } /* We are done with the layer - time to free some resources */ gimp_drawable_detach (layer); if (mask_id != -1) { gimp_drawable_detach (mask); cairo_surface_destroy (mask_image); } } /* We are done with this image - Show it! */ cairo_show_page (cr); cairo_restore (cr); if (exported) gimp_image_delete (image_id); } /* We are done with all the images - time to free the resources */ cairo_surface_destroy (pdf_file); cairo_destroy (cr); fclose (fp); /* Finally done, let's save the parameters */ gimp_set_data (DATA_OPTIMIZE, &optimize, sizeof (optimize)); if (!single_image) { g_strlcpy (multi_page.file_name, file_name, MAX_FILE_NAME_LENGTH); gimp_set_data (DATA_IMAGE_LIST, &multi_page, sizeof (multi_page)); } }
static GimpValueArray * image_convert_indexed_invoker (GimpProcedure *procedure, Gimp *gimp, GimpContext *context, GimpProgress *progress, const GimpValueArray *args, GError **error) { gboolean success = TRUE; GimpImage *image; gint32 dither_type; gint32 palette_type; gint32 num_cols; gboolean alpha_dither; gboolean remove_unused; const gchar *palette; image = gimp_value_get_image (gimp_value_array_index (args, 0), gimp); dither_type = g_value_get_enum (gimp_value_array_index (args, 1)); palette_type = g_value_get_enum (gimp_value_array_index (args, 2)); num_cols = g_value_get_int (gimp_value_array_index (args, 3)); alpha_dither = g_value_get_boolean (gimp_value_array_index (args, 4)); remove_unused = g_value_get_boolean (gimp_value_array_index (args, 5)); palette = g_value_get_string (gimp_value_array_index (args, 6)); if (success) { GimpPalette *pal = NULL; if (gimp_pdb_image_is_not_base_type (image, GIMP_INDEXED, error) && gimp_pdb_image_is_precision (image, GIMP_PRECISION_U8, error) && gimp_item_stack_is_flat (GIMP_ITEM_STACK (gimp_image_get_layers (image)))) { switch (palette_type) { case GIMP_MAKE_PALETTE: if (num_cols < 1 || num_cols > MAXNUMCOLORS) success = FALSE; break; case GIMP_CUSTOM_PALETTE: pal = gimp_pdb_get_palette (gimp, palette, FALSE, error); if (! pal) { success = FALSE; } else if (pal->n_colors > MAXNUMCOLORS) { g_set_error_literal (error, GIMP_PDB_ERROR, GIMP_PDB_ERROR_INVALID_ARGUMENT, _("Cannot convert to a palette " "with more than 256 colors.")); success = FALSE; } break; default: break; } } else { success = FALSE; } if (success) success = gimp_image_convert_type (image, GIMP_INDEXED, num_cols, dither_type, alpha_dither, FALSE, remove_unused, palette_type, pal, NULL, error); } return gimp_procedure_get_return_values (procedure, success, error ? *error : NULL); }
static void lcms_image_transform_rgb (gint32 image, cmsHPROFILE src_profile, cmsHPROFILE dest_profile, GimpColorRenderingIntent intent, gboolean bpc) { cmsHTRANSFORM transform = NULL; DWORD last_format = 0; gint *layers; gint num_layers; gint i; layers = gimp_image_get_layers (image, &num_layers); for (i = 0; i < num_layers; i++) { GimpDrawable *drawable = gimp_drawable_get (layers[i]); DWORD format; switch (drawable->bpp) { case 3: format = TYPE_RGB_8; break; case 4: format = TYPE_RGBA_8; break; default: g_warning ("%s: unexpected bpp", G_STRLOC); continue; } if (! transform || format != last_format) { if (transform) cmsDeleteTransform (transform); transform = cmsCreateTransform (src_profile, format, dest_profile, format, intent, bpc ? cmsFLAGS_BLACKPOINTCOMPENSATION : 0); last_format = format; } if (transform) { lcms_drawable_transform (drawable, transform, (gdouble) i / num_layers, (gdouble) (i + 1) / num_layers); } else { g_warning ("cmsCreateTransform() failed!"); } gimp_drawable_detach (drawable); } if (transform) cmsDeleteTransform(transform); g_free (layers); }