-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi All, Attached is a patch, against svn, which adds ACO importing, and CSS color extraction, for the palette system. The ACO code only reads the version 1 section at the moment, I plan on finishing the version 2 support to extract color names a little later. Color spaces supported are RGB, CMYK, HSV and greyscale, but not Lab. The CSS import extracts colors defined in a .css file. If this patch meets the standards, perhaps someone would like to incorporate it into the repository. This patch would, I believe, enable the closing of Bug #316618 Thanks Nicola. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFGtMldG4yOusCUvb8RAvSVAJoD6KK24CPhq5AXsSzekqXUY3RF4wCfWDpw 5mUdq2GWEYX970J0gHzUWGE= =ZgvZ -----END PGP SIGNATURE-----
Index: app/core/gimppalette-import.c =================================================================== --- app/core/gimppalette-import.c (revision 23113) +++ app/core/gimppalette-import.c (working copy) @@ -511,6 +511,14 @@ palette_list = gimp_palette_load_psp (filename, error); break; + case GIMP_PALETTE_FILE_FORMAT_ACO: + palette_list = gimp_palette_load_aco (filename, error); + break; + + case GIMP_PALETTE_FILE_FORMAT_CSS: + palette_list = gimp_palette_load_css (filename, error); + break; + default: g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ, Index: app/core/gimppalette-load.c =================================================================== --- app/core/gimppalette-load.c (revision 23113) +++ app/core/gimppalette-load.c (working copy) @@ -430,6 +430,224 @@ return g_list_prepend (NULL, palette); } +GList * +gimp_palette_load_aco (const gchar *filename, + GError **error) +{ + GimpPalette *palette; + gchar *palette_name; + gint fd; + guchar color_bytes[4]; + gint format_version; + gint number_of_colors; + gint i; + gchar header[4]; + gchar color_info[10]; + gchar format2_preamble[4]; + gint status; + + g_return_val_if_fail (filename != NULL, NULL); + g_return_val_if_fail (g_path_is_absolute (filename), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + fd = g_open (filename, O_RDONLY | _O_BINARY, 0); + if (! fd) + { + g_set_error (error, + G_FILE_ERROR, g_file_error_from_errno (errno), + _("Could not open '%s' for reading: %s"), + gimp_filename_to_utf8 (filename), g_strerror (errno)); + return NULL; + } + + palette_name = g_filename_display_basename (filename); + palette = GIMP_PALETTE (gimp_palette_new (palette_name)); + g_free (palette_name); + + status = read(fd, header, sizeof (header)); + + if (status < 0) + { + close(fd); + + return g_list_prepend (NULL, palette); + } + + format_version = header[1] + (header[0] << 8); + number_of_colors = header[3] + (header[2] << 8); + + for (i = 0; i < number_of_colors; i++) + { + gint color_space; + gint w, x, y, z; + gboolean color_ok = FALSE; + GimpRGB color; + + read(fd, color_info, sizeof(color_info)); + color_space = color_info[1] + (color_info[0] << 8); + + w = (guchar)color_info[3] + ((guchar)color_info[2] << 8); + x = (guchar)color_info[5] + ((guchar)color_info[4] << 8); + y = (guchar)color_info[7] + ((guchar)color_info[6] << 8); + z = (guchar)color_info[9] + ((guchar)color_info[8] << 8); + + if (color_space == 0) /* RGB */ + { + gdouble R = ((gdouble) w) / 65536.0; + gdouble G = ((gdouble) x) / 65536.0; + gdouble B = ((gdouble) y) / 65536.0; + + gimp_rgba_set( &color, R, G, B, 1.0); + + color_ok = TRUE; + } + else if (color_space == 1) /* HSV */ + { + GimpHSV hsv; + + gdouble H = ((gdouble) w) / 65536.0; + gdouble S = ((gdouble) x) / 65536.0; + gdouble V = ((gdouble) y) / 65536.0; + + gimp_hsva_set ( &hsv, H, S, V, 1.0 ); + gimp_hsv_to_rgb( &hsv, &color); + + color_ok = TRUE; + } + else if (color_space == 2) /* CMYK */ + { + GimpCMYK cmyk; + + gdouble C = 1.0 - (((gdouble) w) / 65536.0); + gdouble M = 1.0 - (((gdouble) x) / 65536.0); + gdouble Y = 1.0 - (((gdouble) y) / 65536.0); + gdouble K = 1.0 - (((gdouble) z) / 65536.0); + + gimp_cmyka_set (&cmyk, C, M, Y, K, 1.0 ); + gimp_cmyk_to_rgb( &cmyk, &color); + + color_ok = TRUE; + } + else if (color_space == 8) /* Grayscale */ + { + gdouble K = 1.0 - (((gdouble) w) / 10000.0); + + gimp_rgba_set( &color, K, K, K, 1.0 ); + + color_ok = TRUE; + } + else if (color_space == 9) /* Wide? CMYK */ + { + GimpCMYK cmyk; + + gdouble C = 1.0 - (((gdouble) w) / 10000.0); + gdouble M = 1.0 - (((gdouble) x) / 10000.0); + gdouble Y = 1.0 - (((gdouble) y) / 10000.0); + gdouble K = 1.0 - (((gdouble) z) / 10000.0); + + gimp_cmyka_set (&cmyk, C, M, Y, K, 1.0 ); + gimp_cmyk_to_rgb( &cmyk, &color); + + color_ok = TRUE; + } + else + { + g_print("Unsupported color space (%d) in ACO file\n", color_space ); + } + + if (format_version == 2) + { + gint number_of_chars; + + read(fd, format2_preamble, sizeof(format2_preamble)); + number_of_chars = format2_preamble[3] + (format2_preamble[2] << 8); + lseek(fd, number_of_chars * 2, SEEK_SET); + } + + if (color_ok) + { + gimp_palette_add_entry (palette, -1, NULL, &color); + } + } + + close(fd); + + return g_list_prepend (NULL, palette); +} + + +GList * +gimp_palette_load_css (const gchar *filename, + GError **error) +{ + GimpPalette *palette; + gchar *palette_name; + FILE *file; + guchar color_bytes[4]; + gint format_version; + gint number_of_colors; + gint i; + gchar header[4]; + gchar color_info[10]; + gchar format2_preamble[4]; + gint status; + gchar str[1024]; + GRegex *pattern1; + GimpRGB color; + + pattern1 = g_regex_new ( ".*color.*:(?P<param>.*\);", G_REGEX_CASELESS, + 0, + error); + if (pattern1 == NULL) + return NULL; + + g_return_val_if_fail (filename != NULL, NULL); + g_return_val_if_fail (g_path_is_absolute (filename), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + file = g_fopen (filename, "rb"); + if (! file) + { + g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_OPEN, + _("Could not open '%s' for reading: %s"), + gimp_filename_to_utf8 (filename), g_strerror (errno)); + return NULL; + } + + palette_name = g_filename_display_basename (filename); + palette = GIMP_PALETTE (gimp_palette_new (palette_name)); + g_free (palette_name); + + do + { + GMatchInfo *matches; + + if (fgets (str, sizeof(str), file) != NULL) + { + if (g_regex_match( pattern1, + str, + 0, + &matches)) + { + gchar *word = g_match_info_fetch_named (matches, "param"); + if (gimp_rgb_parse_css(&color, word, -1)) + { + if ((gimp_palette_get_columns(palette) == 0) || + (gimp_palette_find_entry( palette, &color, NULL) == NULL)) + { + gimp_palette_add_entry (palette, -1, NULL, &color); + } + } + g_free (word); + + } + } + } while (! feof(file) ); + fclose(file); + + return g_list_prepend (NULL, palette); +} + GimpPaletteFileFormat gimp_palette_load_detect_format (const gchar *filename) { @@ -458,6 +676,23 @@ } } + gchar *lower_filename = g_strdown(g_strdup(filename)); + if (g_str_has_suffix (lower_filename, ".aco")) + { + format = GIMP_PALETTE_FILE_FORMAT_ACO; + close (fd); /* ensure that if the .aco file is 768 bytes it + doesn't get mistaken for a ACT file */ + return format; + } + if (g_str_has_suffix (lower_filename, ".css")) + { + format = GIMP_PALETTE_FILE_FORMAT_CSS; + close (fd); /* ensure that if the .css file is 768 bytes it + doesn't get mistaken for a ACT file */ + return format; + } + g_free(lower_filename); + if (fstat (fd, &file_stat) >= 0) { if (file_stat.st_size == 768) Index: app/core/gimppalette-load.h =================================================================== --- app/core/gimppalette-load.h (revision 23113) +++ app/core/gimppalette-load.h (working copy) @@ -29,7 +29,9 @@ GIMP_PALETTE_FILE_FORMAT_GPL, /* GIMP palette */ GIMP_PALETTE_FILE_FORMAT_RIFF_PAL, /* RIFF palette */ GIMP_PALETTE_FILE_FORMAT_ACT, /* Photoshop binary color palette */ - GIMP_PALETTE_FILE_FORMAT_PSP_PAL /* JASC's Paint Shop Pro color palette */ + GIMP_PALETTE_FILE_FORMAT_PSP_PAL, /* JASC's Paint Shop Pro color palette */ + GIMP_PALETTE_FILE_FORMAT_ACO, /* Photoshop ACO color file */ + GIMP_PALETTE_FILE_FORMAT_CSS /* Extract CSS colors */ } GimpPaletteFileFormat; @@ -41,6 +43,10 @@ GError **error); GList * gimp_palette_load_psp (const gchar *filename, GError **error); +GList * gimp_palette_load_aco (const gchar *filename, + GError **error); +GList * gimp_palette_load_css (const gchar *filename, + GError **error); GimpPaletteFileFormat gimp_palette_load_detect_format (const gchar *filename);
Attachment:
gimp_diff.sig
Description: Binary data
_______________________________________________ Gimp-developer mailing list Gimp-developer@xxxxxxxxxxxxxxxxxxxxxx https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer