GList * gimp_palette_load (GimpContext *context, GFile *file, GInputStream *input, GError **error) { GimpPalette *palette = NULL; GimpPaletteEntry *entry; GDataInputStream *data_input; gchar *str; gsize str_len; gchar *tok; gint r, g, b; gint linenum; g_return_val_if_fail (G_IS_FILE (file), NULL); g_return_val_if_fail (G_IS_INPUT_STREAM (input), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); data_input = g_data_input_stream_new (input); r = g = b = 0; linenum = 1; str_len = 1024; str = gimp_data_input_stream_read_line_always (data_input, &str_len, NULL, error); if (! str) goto failed; if (! g_str_has_prefix (str, "GIMP Palette")) { g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ, _("Missing magic header.")); g_free (str); goto failed; } g_free (str); palette = g_object_new (GIMP_TYPE_PALETTE, "mime-type", "application/x-gimp-palette", NULL); linenum++; str_len = 1024; str = gimp_data_input_stream_read_line_always (data_input, &str_len, NULL, error); if (! str) goto failed; if (g_str_has_prefix (str, "Name: ")) { gchar *utf8; utf8 = gimp_any_to_utf8 (g_strstrip (str + strlen ("Name: ")), -1, _("Invalid UTF-8 string in palette file '%s'"), gimp_file_get_utf8_name (file)); gimp_object_take_name (GIMP_OBJECT (palette), utf8); g_free (str); linenum++; str_len = 1024; str = gimp_data_input_stream_read_line_always (data_input, &str_len, NULL, error); if (! str) goto failed; if (g_str_has_prefix (str, "Columns: ")) { gint columns; if (! gimp_ascii_strtoi (g_strstrip (str + strlen ("Columns: ")), NULL, 10, &columns)) { g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ, _("Invalid column count.")); g_free (str); goto failed; } if (columns < 0 || columns > 256) { g_message (_("Reading palette file '%s': " "Invalid number of columns in line %d. " "Using default value."), gimp_file_get_utf8_name (file), linenum); columns = 0; } gimp_palette_set_columns (palette, columns); g_free (str); linenum++; str_len = 1024; str = gimp_data_input_stream_read_line_always (data_input, &str_len, NULL, error); if (! str) goto failed; } } else /* old palette format */ { gimp_object_take_name (GIMP_OBJECT (palette), g_path_get_basename (gimp_file_get_utf8_name (file))); } while (str) { GError *my_error = NULL; if (str[0] != '#' && str[0] != '\0') { tok = strtok (str, " \t"); if (tok) r = atoi (tok); else g_message (_("Reading palette file '%s': " "Missing RED component in line %d."), gimp_file_get_utf8_name (file), linenum); tok = strtok (NULL, " \t"); if (tok) g = atoi (tok); else g_message (_("Reading palette file '%s': " "Missing GREEN component in line %d."), gimp_file_get_utf8_name (file), linenum); tok = strtok (NULL, " \t"); if (tok) b = atoi (tok); else g_message (_("Reading palette file '%s': " "Missing BLUE component in line %d."), gimp_file_get_utf8_name (file), linenum); /* optional name */ tok = strtok (NULL, "\n"); if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) g_message (_("Reading palette file '%s': " "RGB value out of range in line %d."), gimp_file_get_utf8_name (file), linenum); /* don't call gimp_palette_add_entry here, it's rather inefficient */ entry = g_slice_new0 (GimpPaletteEntry); gimp_rgba_set_uchar (&entry->color, (guchar) r, (guchar) g, (guchar) b, 255); entry->name = g_strdup (tok ? tok : _("Untitled")); entry->position = gimp_palette_get_n_colors (palette); palette->colors = g_list_prepend (palette->colors, entry); palette->n_colors++; } g_free (str); linenum++; str_len = 1024; str = g_data_input_stream_read_line (data_input, &str_len, NULL, &my_error); if (! str && my_error) { g_message (_("Reading palette file '%s': " "Read %d colors from truncated file: %s"), gimp_file_get_utf8_name (file), g_list_length (palette->colors), my_error->message); g_clear_error (&my_error); } } palette->colors = g_list_reverse (palette->colors); g_object_unref (data_input); return g_list_prepend (NULL, palette); failed: g_object_unref (data_input); if (palette) g_object_unref (palette); g_prefix_error (error, _("In line %d of palette file: "), linenum); return NULL; }
static void gimp_view_renderer_palette_render (GimpViewRenderer *renderer, GtkWidget *widget) { GimpViewRendererPalette *renderpal = GIMP_VIEW_RENDERER_PALETTE (renderer); GimpPalette *palette; GimpColorTransform *transform; guchar *row; guchar *dest; GList *list; gdouble cell_width; gint grid_width; gint dest_stride; gint y; palette = GIMP_PALETTE (renderer->viewable); if (gimp_palette_get_n_colors (palette) == 0) return; grid_width = renderpal->draw_grid ? 1 : 0; if (renderpal->cell_size > 0) { gint n_columns = gimp_palette_get_columns (palette); if (n_columns > 0) cell_width = MAX ((gdouble) renderpal->cell_size, (gdouble) (renderer->width - grid_width) / (gdouble) n_columns); else cell_width = renderpal->cell_size; } else { gint n_columns = gimp_palette_get_columns (palette); if (n_columns > 0) cell_width = ((gdouble) (renderer->width - grid_width) / (gdouble) n_columns); else cell_width = (gdouble) (renderer->width - grid_width) / 16.0; } cell_width = MAX (4.0, cell_width); renderpal->cell_width = cell_width; renderpal->columns = (gdouble) (renderer->width - grid_width) / cell_width; renderpal->rows = gimp_palette_get_n_colors (palette) / renderpal->columns; if (gimp_palette_get_n_colors (palette) % renderpal->columns) renderpal->rows += 1; renderpal->cell_height = MAX (4, ((renderer->height - grid_width) / renderpal->rows)); if (! renderpal->draw_grid) renderpal->cell_height = MIN (renderpal->cell_height, renderpal->cell_width); list = gimp_palette_get_colors (palette); if (! renderer->surface) renderer->surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, renderer->width, renderer->height); cairo_surface_flush (renderer->surface); row = g_new (guchar, renderer->width * 4); dest = cairo_image_surface_get_data (renderer->surface); dest_stride = cairo_image_surface_get_stride (renderer->surface); transform = gimp_view_renderer_get_color_transform (renderer, widget, babl_format ("cairo-RGB24"), babl_format ("cairo-RGB24")); for (y = 0; y < renderer->height; y++) { if ((y % renderpal->cell_height) == 0) { guchar r, g, b; gint x; gint n = 0; guchar *d = row; memset (row, renderpal->draw_grid ? 0 : 255, renderer->width * 4); r = g = b = (renderpal->draw_grid ? 0 : 255); for (x = 0; x < renderer->width; x++, d += 4) { if ((x % renderpal->cell_width) == 0) { if (list && n < renderpal->columns && renderer->width - x >= renderpal->cell_width) { GimpPaletteEntry *entry = list->data; list = g_list_next (list); n++; gimp_rgb_get_uchar (&entry->color, &r, &g, &b); } else { r = g = b = (renderpal->draw_grid ? 0 : 255); } } if (renderpal->draw_grid && (x % renderpal->cell_width) == 0) { GIMP_CAIRO_RGB24_SET_PIXEL (d, 0, 0, 0); } else { GIMP_CAIRO_RGB24_SET_PIXEL (d, r, g, b); } } } if (renderpal->draw_grid && (y % renderpal->cell_height) == 0) { memset (dest, 0, renderer->width * 4); } else { if (transform) { gimp_color_transform_process_pixels (transform, babl_format ("cairo-RGB24"), row, babl_format ("cairo-RGB24"), dest, renderer->width); } else { memcpy (dest, row, renderer->width * 4); } } dest += dest_stride; } g_free (row); cairo_surface_mark_dirty (renderer->surface); }
void gimp_palette_editor_zoom (GimpPaletteEditor *editor, GimpZoomType zoom_type) { GimpPalette *palette; gdouble zoom_factor; g_return_if_fail (GIMP_IS_PALETTE_EDITOR (editor)); palette = GIMP_PALETTE (GIMP_DATA_EDITOR (editor)->data); if (! palette) return; zoom_factor = editor->zoom_factor; switch (zoom_type) { case GIMP_ZOOM_IN_MAX: case GIMP_ZOOM_IN_MORE: case GIMP_ZOOM_IN: zoom_factor += 0.1; break; case GIMP_ZOOM_OUT_MORE: case GIMP_ZOOM_OUT: zoom_factor -= 0.1; break; case GIMP_ZOOM_OUT_MAX: case GIMP_ZOOM_TO: /* abused as ZOOM_ALL */ { GtkWidget *scrolled_win = GIMP_DATA_EDITOR (editor)->view; GtkWidget *viewport = gtk_bin_get_child (GTK_BIN (scrolled_win)); GtkAllocation allocation; gint columns; gint rows; gtk_widget_get_allocation (viewport, &allocation); columns = gimp_palette_get_columns (palette); if (columns == 0) columns = COLUMNS; rows = gimp_palette_get_n_colors (palette) / columns; if (gimp_palette_get_n_colors (palette) % columns) rows += 1; rows = MAX (1, rows); zoom_factor = (((gdouble) allocation.height - 2 * SPACING) / (gdouble) rows - SPACING) / ENTRY_HEIGHT; } break; } zoom_factor = CLAMP (zoom_factor, 0.1, 4.0); editor->columns = gimp_palette_get_columns (palette); if (editor->columns == 0) editor->columns = COLUMNS; palette_editor_resize (editor, editor->last_width, zoom_factor); palette_editor_scroll_top_left (editor); }
static void palette_import_make_palette (ImportDialog *dialog) { GimpPalette *palette = NULL; const gchar *palette_name; gint n_colors; gint n_columns; gint threshold; palette_name = gtk_entry_get_text (GTK_ENTRY (dialog->entry)); if (! palette_name || ! strlen (palette_name)) palette_name = _("Untitled"); n_colors = ROUND (gtk_adjustment_get_value (dialog->num_colors)); n_columns = ROUND (gtk_adjustment_get_value (dialog->columns)); threshold = ROUND (gtk_adjustment_get_value (dialog->threshold)); switch (dialog->import_type) { case GRADIENT_IMPORT: { GimpGradient *gradient; gradient = gimp_context_get_gradient (dialog->context); palette = gimp_palette_import_from_gradient (gradient, dialog->context, FALSE, palette_name, n_colors); } break; case IMAGE_IMPORT: { GimpImage *image = gimp_context_get_image (dialog->context); gboolean sample_merged; gboolean selection_only; sample_merged = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->sample_merged_toggle)); selection_only = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->selection_only_toggle)); if (gimp_image_base_type (image) == GIMP_INDEXED) { palette = gimp_palette_import_from_indexed_image (image, dialog->context, palette_name); } else if (sample_merged) { palette = gimp_palette_import_from_image (image, dialog->context, palette_name, n_colors, threshold, selection_only); } else { GimpDrawable *drawable; drawable = GIMP_DRAWABLE (gimp_image_get_active_layer (image)); palette = gimp_palette_import_from_drawable (drawable, dialog->context, palette_name, n_colors, threshold, selection_only); } } break; case FILE_IMPORT: { gchar *filename; GError *error = NULL; filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog->file_chooser)); palette = gimp_palette_import_from_file (dialog->context, filename, palette_name, &error); g_free (filename); if (! palette) { gimp_message_literal (dialog->context->gimp, G_OBJECT (dialog->dialog), GIMP_MESSAGE_ERROR, error->message); g_error_free (error); } } break; } if (palette) { if (dialog->palette) g_object_unref (dialog->palette); gimp_palette_set_columns (palette, n_columns); gimp_view_set_viewable (GIMP_VIEW (dialog->preview), GIMP_VIEWABLE (palette)); dialog->palette = palette; } gtk_widget_set_visible (dialog->no_colors_label, dialog->palette && gimp_palette_get_n_colors (dialog->palette) > 0); }
static gboolean gimp_palette_view_focus (GtkWidget *widget, GtkDirectionType direction) { GimpPaletteView *view = GIMP_PALETTE_VIEW (widget); GimpPalette *palette; palette = GIMP_PALETTE (GIMP_VIEW (view)->renderer->viewable); if (gtk_widget_get_can_focus (widget) && ! gtk_widget_has_focus (widget)) { gtk_widget_grab_focus (widget); if (! view->selected && palette && gimp_palette_get_n_colors (palette) > 0) { GimpPaletteEntry *entry = gimp_palette_get_entry (palette, 0); gimp_palette_view_select_entry (view, entry); } return TRUE; } if (view->selected) { GimpViewRendererPalette *renderer; gint skip = 0; renderer = GIMP_VIEW_RENDERER_PALETTE (GIMP_VIEW (view)->renderer); switch (direction) { case GTK_DIR_UP: skip = -renderer->columns; break; case GTK_DIR_DOWN: skip = renderer->columns; break; case GTK_DIR_LEFT: skip = -1; break; case GTK_DIR_RIGHT: skip = 1; break; case GTK_DIR_TAB_FORWARD: case GTK_DIR_TAB_BACKWARD: return FALSE; } if (skip != 0) { GimpPaletteEntry *entry; gint position; position = view->selected->position + skip; entry = gimp_palette_get_entry (palette, position); if (entry) gimp_palette_view_select_entry (view, entry); } return TRUE; } return FALSE; }