diff --git a/app/Makefile.am b/app/Makefile.am index 052426d927..c6774f0492 100644 --- a/app/Makefile.am +++ b/app/Makefile.am @@ -28,6 +28,7 @@ SUBDIRS = \ plug-in \ xcf \ file \ + file-data \ pdb \ widgets \ propgui \ @@ -159,6 +160,7 @@ gimpconsoleldadd = \ vectors/libappvectors.a \ core/libappcore.a \ file/libappfile.a \ + file-data/libappfile-data.a \ text/libapptext.a \ paint/libapppaint.a \ operations/libappoperations.a \ diff --git a/app/core/gimp.c b/app/core/gimp.c index 08ffced6ad..ce6d7f8732 100644 --- a/app/core/gimp.c +++ b/app/core/gimp.c @@ -41,6 +41,7 @@ #include "paint/gimp-paint.h" #include "xcf/xcf.h" +#include "file-data/file-data.h" #include "gimp.h" #include "gimp-contexts.h" @@ -284,6 +285,7 @@ gimp_constructed (GObject *object) gimp->pdb = gimp_pdb_new (gimp); xcf_init (gimp); + file_data_init (gimp); /* create user and default context */ gimp_contexts_init (gimp); @@ -390,6 +392,7 @@ gimp_finalize (GObject *object) g_clear_object (&gimp->tool_info_list); } + file_data_exit (gimp); xcf_exit (gimp); g_clear_object (&gimp->pdb); diff --git a/app/file-data/.gitignore b/app/file-data/.gitignore new file mode 100644 index 0000000000..e882491b0b --- /dev/null +++ b/app/file-data/.gitignore @@ -0,0 +1,7 @@ +/Makefile +/Makefile.in +/.deps +/.libs +/*.lo +/libappfile-data.a +/libappfile-data.la diff --git a/app/file-data/Makefile.am b/app/file-data/Makefile.am new file mode 100644 index 0000000000..f703ca51d9 --- /dev/null +++ b/app/file-data/Makefile.am @@ -0,0 +1,20 @@ +## Process this file with automake to produce Makefile.in + +AM_CPPFLAGS = \ + -DG_LOG_DOMAIN=\"Gimp-File-Data\" \ + -I$(top_builddir) \ + -I$(top_srcdir) \ + -I$(top_builddir)/app \ + -I$(top_srcdir)/app \ + $(CAIRO_CFLAGS) \ + $(GEGL_CFLAGS) \ + $(GDK_PIXBUF_CFLAGS) \ + -I$(includedir) + +noinst_LIBRARIES = libappfile-data.a + +libappfile_data_a_SOURCES = \ + file-data.c \ + file-data.h \ + file-data-gbr.c \ + file-data-gbr.h diff --git a/app/file-data/file-data-gbr.c b/app/file-data/file-data-gbr.c new file mode 100644 index 0000000000..56c9f008a4 --- /dev/null +++ b/app/file-data/file-data-gbr.c @@ -0,0 +1,240 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "config.h" + +#include +#include + +#include "libgimpbase/gimpbase.h" + +#include "core/core-types.h" + +#include "core/gimp.h" +#include "core/gimpbrush.h" +#include "core/gimpbrush-load.h" +#include "core/gimpdrawable.h" +#include "core/gimpimage.h" +#include "core/gimplayer-new.h" +#include "core/gimpparamspecs.h" +#include "core/gimptempbuf.h" + +#include "pdb/gimpprocedure.h" + +#include "file-data-gbr.h" + +#include "gimp-intl.h" + + +/* local function prototypes */ + +static GimpImage * file_gbr_brush_to_image (Gimp *gimp, + GimpBrush *brush); +static GimpBrush * file_gbr_image_to_brush (GimpImage *image); + + +/* public functions */ + +GimpValueArray * +file_gbr_load_invoker (GimpProcedure *procedure, + Gimp *gimp, + GimpContext *context, + GimpProgress *progress, + const GimpValueArray *args, + GError **error) +{ + GimpValueArray *return_vals; + GimpImage *image = NULL; + const gchar *uri; + GFile *file; + GInputStream *input; + GError *my_error = NULL; + + gimp_set_busy (gimp); + + uri = g_value_get_string (gimp_value_array_index (args, 1)); + file = g_file_new_for_uri (uri); + + input = G_INPUT_STREAM (g_file_read (file, NULL, &my_error)); + + if (input) + { + GimpBrush *brush = gimp_brush_load_brush (context, file, input, error); + + if (brush) + { + image = file_gbr_brush_to_image (gimp, brush); + g_object_unref (brush); + } + + g_object_unref (input); + } + else + { + g_propagate_prefixed_error (error, my_error, + _("Could not open '%s' for reading: "), + gimp_file_get_utf8_name (file)); + } + + g_object_unref (file); + + return_vals = gimp_procedure_get_return_values (procedure, image != NULL, + error ? *error : NULL); + + if (image) + gimp_value_set_image (gimp_value_array_index (return_vals, 1), image); + + gimp_unset_busy (gimp); + + return return_vals; +} + +GimpValueArray * +file_gbr_save_invoker (GimpProcedure *procedure, + Gimp *gimp, + GimpContext *context, + GimpProgress *progress, + const GimpValueArray *args, + GError **error) +{ + GimpValueArray *return_vals; + GimpImage *image; + GimpBrush *brush; + const gchar *uri; + GFile *file; + gboolean success; + + gimp_set_busy (gimp); + + image = gimp_value_get_image (gimp_value_array_index (args, 1), gimp); + uri = g_value_get_string (gimp_value_array_index (args, 3)); + file = g_file_new_for_uri (uri); + + brush = file_gbr_image_to_brush (image); + + gimp_data_set_file (GIMP_DATA (brush), file, TRUE, TRUE); + + success = gimp_data_save (GIMP_DATA (brush), error); + + g_object_unref (brush); + g_object_unref (file); + + return_vals = gimp_procedure_get_return_values (procedure, success, + error ? *error : NULL); + + gimp_unset_busy (gimp); + + return return_vals; +} + + +/* private functions */ + +static GimpImage * +file_gbr_brush_to_image (Gimp *gimp, + GimpBrush *brush) +{ + GimpImage *image; + GimpLayer *layer; + const Babl *format; + const gchar *name; + GimpImageBaseType base_type; + gboolean alpha; + gint width; + gint height; + GimpTempBuf *mask = gimp_brush_get_mask (brush); + GimpTempBuf *pixmap = gimp_brush_get_pixmap (brush); + GeglBuffer *buffer; + GimpParasite *parasite; + + if (pixmap) + { + base_type = GIMP_RGB; + alpha = TRUE; + } + else + { + base_type = GIMP_GRAY; + alpha = FALSE; + } + + name = gimp_object_get_name (brush); + width = gimp_temp_buf_get_width (mask); + height = gimp_temp_buf_get_height (mask); + + image = gimp_image_new (gimp, width, height, base_type, + GIMP_PRECISION_U8_PERCEPTUAL); + + parasite = gimp_parasite_new ("gimp-brush-name", + GIMP_PARASITE_PERSISTENT, + strlen (name) + 1, name); + gimp_image_parasite_attach (image, parasite); + gimp_parasite_free (parasite); + + format = gimp_image_get_layer_format (image, alpha); + + layer = gimp_layer_new (image, width, height, format, name, + 1.0, GIMP_LAYER_MODE_NORMAL); + gimp_image_add_layer (image, layer, NULL, 0, FALSE); + + buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (layer)); + + if (pixmap) + { + guchar *pixmap_data; + guchar *mask_data; + guchar *p; + guchar *m; + gint i; + + gegl_buffer_set (buffer, GEGL_RECTANGLE (0, 0, width, height), 0, + babl_format ("R'G'B' u8"), + gimp_temp_buf_get_data (pixmap), GEGL_AUTO_ROWSTRIDE); + + pixmap_data = gegl_buffer_linear_open (buffer, NULL, NULL, NULL); + mask_data = gimp_temp_buf_get_data (mask); + + for (i = 0, p = pixmap_data, m = mask_data; + i < width * height; + i++, p += 4, m += 1) + { + p[3] = *m; + } + + gegl_buffer_linear_close (buffer, pixmap_data); + } + else + { + guchar *mask_data = gimp_temp_buf_get_data (mask); + gint i; + + for (i = 0; i < width * height; i++) + mask_data[i] = 255 - mask_data[i]; + + gegl_buffer_set (buffer, GEGL_RECTANGLE (0, 0, width, height), 0, + babl_format ("Y' u8"), + mask_data, GEGL_AUTO_ROWSTRIDE); + } + + return image; +} + +static GimpBrush * +file_gbr_image_to_brush (GimpImage *image) +{ + return NULL; +} diff --git a/app/file-data/file-data-gbr.h b/app/file-data/file-data-gbr.h new file mode 100644 index 0000000000..3cc355ef50 --- /dev/null +++ b/app/file-data/file-data-gbr.h @@ -0,0 +1,37 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __FILE_DATA_GBR_H__ +#define __FILE_DATA_GBR_H__ + + +GimpValueArray * file_gbr_load_invoker (GimpProcedure *procedure, + Gimp *gimp, + GimpContext *context, + GimpProgress *progress, + const GimpValueArray *args, + GError **error); + +GimpValueArray * file_gbr_save_invoker (GimpProcedure *procedure, + Gimp *gimp, + GimpContext *context, + GimpProgress *progress, + const GimpValueArray *args, + GError **error); + + +#endif /* __FILE_DATA_GBR_H__ */ diff --git a/app/file-data/file-data.c b/app/file-data/file-data.c new file mode 100644 index 0000000000..953cec7246 --- /dev/null +++ b/app/file-data/file-data.c @@ -0,0 +1,118 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "config.h" + +#include +#include + +#include "libgimpbase/gimpbase.h" + +#include "core/core-types.h" + +#include "core/gimp.h" +#include "core/gimpparamspecs.h" + +#include "plug-in/gimppluginmanager.h" +#include "plug-in/gimppluginprocedure.h" + +#include "file-data.h" +#include "file-data-gbr.h" + +#include "gimp-intl.h" + + +void +file_data_init (Gimp *gimp) +{ + GimpPlugInProcedure *proc; + GFile *file; + GimpProcedure *procedure; + + g_return_if_fail (GIMP_IS_GIMP (gimp)); + + /* file-gbr-load */ + file = g_file_new_for_path ("file-gbr-load"); + procedure = gimp_plug_in_procedure_new (GIMP_PLUGIN, file); + g_object_unref (file); + + procedure->proc_type = GIMP_INTERNAL; + procedure->marshal_func = file_gbr_load_invoker; + + proc = GIMP_PLUG_IN_PROCEDURE (procedure); + proc->menu_label = g_strdup (N_("GIMP brush")); + gimp_plug_in_procedure_set_icon (proc, GIMP_ICON_TYPE_ICON_NAME, + (const guint8 *) "gimp-brush", + strlen ("gimp-brush") + 1); + gimp_plug_in_procedure_set_image_types (proc, NULL); + gimp_plug_in_procedure_set_file_proc (proc, "gbr, gbp", "", + "20, string, GIMP"); + gimp_plug_in_procedure_set_mime_types (proc, "image/gimp-x-gbr"); + gimp_plug_in_procedure_set_handles_uri (proc); + + gimp_object_set_static_name (GIMP_OBJECT (procedure), "file-gbr-load"); + gimp_procedure_set_static_strings (procedure, + "file-gbr-load", + "Loads GIMP brushes", + "Loads GIMP brushes (1 or 4 bpp " + "and old .gpb format)", + "Tim Newsome, Jens Lautenbacher, " + "Sven Neumann, Michael Natterer", + "Tim Newsome, Jens Lautenbacher, " + "Sven Neumann, Michael Natterer", + "1995-2019", + NULL); + + gimp_procedure_add_argument (procedure, + gimp_param_spec_int32 ("dummy-param", + "Dummy Param", + "Dummy parameter", + G_MININT32, G_MAXINT32, 0, + GIMP_PARAM_READWRITE)); + gimp_procedure_add_argument (procedure, + gimp_param_spec_string ("uri", + "URI", + "The URI of the file " + "to load", + TRUE, FALSE, TRUE, + NULL, + GIMP_PARAM_READWRITE)); + gimp_procedure_add_argument (procedure, + gimp_param_spec_string ("raw-uri", + "Raw URI", + "The URI of the file " + "to load", + TRUE, FALSE, TRUE, + NULL, + GIMP_PARAM_READWRITE)); + + gimp_procedure_add_return_value (procedure, + gimp_param_spec_image_id ("image", + "Image", + "Output image", + gimp, FALSE, + GIMP_PARAM_READWRITE)); + + gimp_plug_in_manager_add_procedure (gimp->plug_in_manager, proc); + g_object_unref (procedure); +} + +void +file_data_exit (Gimp *gimp) +{ + g_return_if_fail (GIMP_IS_GIMP (gimp)); +} diff --git a/app/file-data/file-data.h b/app/file-data/file-data.h new file mode 100644 index 0000000000..a36381d81a --- /dev/null +++ b/app/file-data/file-data.h @@ -0,0 +1,26 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __FILE_DATA_H__ +#define __FILE_DATA_H__ + + +void file_data_init (Gimp *gimp); +void file_data_exit (Gimp *gimp); + + +#endif /* __FILE_DATA_H__ */ diff --git a/configure.ac b/configure.ac index 610054d47d..63f81cfac9 100644 --- a/configure.ac +++ b/configure.ac @@ -2773,6 +2773,7 @@ app/gegl/Makefile app/dialogs/Makefile app/display/Makefile app/file/Makefile +app/file-data/Makefile app/gui/Makefile app/menus/Makefile app/paint/Makefile diff --git a/plug-ins/common/file-gbr.c b/plug-ins/common/file-gbr.c index d104185be2..580c1a4ce5 100644 --- a/plug-ins/common/file-gbr.c +++ b/plug-ins/common/file-gbr.c @@ -43,7 +43,6 @@ #include "libgimp/stdplugins-intl.h" -#define LOAD_PROC "file-gbr-load" #define SAVE_PROC "file-gbr-save" #define PLUG_IN_BINARY "file-gbr" #define PLUG_IN_ROLE "gimp-file-gbr" @@ -65,8 +64,6 @@ static void run (const gchar *name, gint *nreturn_vals, GimpParam **return_vals); -static gint32 load_image (GFile *file, - GError **error); static gboolean save_image (GFile *file, gint32 image_ID, gint32 drawable_ID, @@ -100,17 +97,6 @@ MAIN () static void query (void) { - static const GimpParamDef load_args[] = - { - { GIMP_PDB_INT32, "run-mode", "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }" }, - { GIMP_PDB_STRING, "uri", "The URI of the file to load" }, - { GIMP_PDB_STRING, "raw-uri", "The URI of the file to load" } - }; - static const GimpParamDef load_return_vals[] = - { - { GIMP_PDB_IMAGE, "image", "Output image" } - }; - static const GimpParamDef save_args[] = { { GIMP_PDB_INT32, "run-mode", "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }" }, @@ -122,28 +108,6 @@ query (void) { GIMP_PDB_STRING, "description", "Short description of the brush" } }; - gimp_install_procedure (LOAD_PROC, - "Loads GIMP brushes", - "Loads GIMP brushes (1 or 4 bpp and old .gpb format)", - "Tim Newsome, Jens Lautenbacher, Sven Neumann", - "Tim Newsome, Jens Lautenbacher, Sven Neumann", - "1997-2005", - N_("GIMP brush"), - NULL, - GIMP_PLUGIN, - G_N_ELEMENTS (load_args), - G_N_ELEMENTS (load_return_vals), - load_args, load_return_vals); - - gimp_plugin_icon_register (LOAD_PROC, GIMP_ICON_TYPE_ICON_NAME, - (const guint8 *) GIMP_ICON_BRUSH); - gimp_register_file_handler_mime (LOAD_PROC, "image/x-gimp-gbr"); - gimp_register_file_handler_uri (LOAD_PROC); - gimp_register_magic_load_handler (LOAD_PROC, - "gbr, gpb", - "", - "20, string, GIMP"); - gimp_install_procedure (SAVE_PROC, "Exports files in the GIMP brush file format", "Exports files in the GIMP brush file format", @@ -189,23 +153,7 @@ run (const gchar *name, values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR; - if (strcmp (name, LOAD_PROC) == 0) - { - image_ID = load_image (g_file_new_for_uri (param[1].data.d_string), - &error); - - if (image_ID != -1) - { - *nreturn_vals = 2; - values[1].type = GIMP_PDB_IMAGE; - values[1].data.d_image = image_ID; - } - else - { - status = GIMP_PDB_EXECUTION_ERROR; - } - } - else if (strcmp (name, SAVE_PROC) == 0) + if (strcmp (name, SAVE_PROC) == 0) { GFile *file; GimpParasite *parasite; @@ -342,331 +290,6 @@ run (const gchar *name, values[0].data.d_status = status; } -static gint32 -load_image (GFile *file, - GError **error) -{ - GInputStream *input; - gchar *name; - GimpBrushHeader bh; - guchar *brush_buf = NULL; - gint32 image_ID; - gint32 layer_ID; - GimpParasite *parasite; - GeglBuffer *buffer; - const Babl *format; - GimpImageBaseType base_type; - GimpImageType image_type; - gsize bytes_read; - gsize size; - gint i; - - gimp_progress_init_printf (_("Opening '%s'"), - g_file_get_parse_name (file)); - - input = G_INPUT_STREAM (g_file_read (file, NULL, error)); - if (! input) - return -1; - - size = G_STRUCT_OFFSET (GimpBrushHeader, magic_number); - - if (! g_input_stream_read_all (input, &bh, size, - &bytes_read, NULL, error) || - bytes_read != size) - { - g_object_unref (input); - return -1; - } - - /* rearrange the bytes in each unsigned int */ - bh.header_size = g_ntohl (bh.header_size); - bh.version = g_ntohl (bh.version); - bh.width = g_ntohl (bh.width); - bh.height = g_ntohl (bh.height); - bh.bytes = g_ntohl (bh.bytes); - - /* Sanitize values */ - if ((bh.width == 0) || (bh.width > GIMP_BRUSH_MAX_SIZE) || - (bh.height == 0) || (bh.height > GIMP_BRUSH_MAX_SIZE) || - ((bh.bytes != 1) && (bh.bytes != 2) && (bh.bytes != 4) && - (bh.bytes != 18)) || - (G_MAXSIZE / bh.width / bh.height / MAX (4, bh.bytes) < 1)) - { - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, - _("Invalid header data in '%s': width=%lu, height=%lu, " - "bytes=%lu"), g_file_get_parse_name (file), - (gulong) bh.width, - (gulong) bh.height, - (gulong) bh.bytes); - return -1; - } - - switch (bh.version) - { - case 1: - /* Version 1 didn't have a magic number and had no spacing */ - bh.spacing = 25; - bh.header_size += 8; - if (bh.header_size < sizeof (GimpBrushHeader)) - { - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, - _("Unsupported brush format")); - g_object_unref (input); - return -1; - } - break; - - case 2: - case 3: /* cinepaint brush */ - size = sizeof (bh.magic_number) + sizeof (bh.spacing); - - if (! g_input_stream_read_all (input, - (guchar *) &bh + - G_STRUCT_OFFSET (GimpBrushHeader, - magic_number), size, - &bytes_read, NULL, error) || - bytes_read != size) - { - g_object_unref (input); - return -1; - } - - bh.magic_number = g_ntohl (bh.magic_number); - bh.spacing = g_ntohl (bh.spacing); - - if (bh.version == 3) - { - if (bh.bytes == 18 /* FLOAT16_GRAY_GIMAGE */) - { - bh.bytes = 2; - } - else - { - g_message (_("Unsupported brush format")); - g_object_unref (input); - return -1; - } - } - - if (bh.magic_number == GIMP_BRUSH_MAGIC && - bh.header_size > sizeof (GimpBrushHeader)) - break; - - default: - g_message (_("Unsupported brush format")); - g_object_unref (input); - return -1; - } - - if ((size = (bh.header_size - sizeof (GimpBrushHeader))) > 0) - { - gchar *temp; - - if (size > GIMP_BRUSH_MAX_NAME) - { - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, - _("Invalid header data in '%s': " - "Brush name is too long: %lu"), - gimp_file_get_utf8_name (file), - (gulong) size); - return -1; - } - - temp = g_new0 (gchar, size + 1); - - if (! g_input_stream_read_all (input, temp, size, - &bytes_read, NULL, error) || - bytes_read != size) - { - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, - _("Error in GIMP brush file '%s'"), - g_file_get_parse_name (file)); - g_object_unref (input); - g_free (temp); - return -1; - } - - name = gimp_any_to_utf8 (temp, size - 1, - _("Invalid UTF-8 string in brush file '%s'."), - g_file_get_parse_name (file)); - g_free (temp); - } - else - { - name = g_strdup (_("Unnamed")); - } - - /* Now there's just raw data left. */ - - size = (gsize) bh.width * bh.height * bh.bytes; - brush_buf = g_malloc (size); - - if (! g_input_stream_read_all (input, brush_buf, size, - &bytes_read, NULL, error) || - bytes_read != size) - { - g_object_unref (input); - g_free (brush_buf); - g_free (name); - return -1; - } - - switch (bh.bytes) - { - case 1: - { - GimpPatternHeader ph; - - /* For backwards-compatibility, check if a pattern follows. - * The obsolete .gpb format did it this way. - */ - - if (g_input_stream_read_all (input, &ph, sizeof (GimpPatternHeader), - &bytes_read, NULL, NULL) && - bytes_read == sizeof (GimpPatternHeader)) - { - /* rearrange the bytes in each unsigned int */ - ph.header_size = g_ntohl (ph.header_size); - ph.version = g_ntohl (ph.version); - ph.width = g_ntohl (ph.width); - ph.height = g_ntohl (ph.height); - ph.bytes = g_ntohl (ph.bytes); - ph.magic_number = g_ntohl (ph.magic_number); - - if (ph.magic_number == GIMP_PATTERN_MAGIC && - ph.version == 1 && - ph.header_size > sizeof (GimpPatternHeader) && - ph.bytes == 3 && - ph.width == bh.width && - ph.height == bh.height && - g_input_stream_skip (input, - ph.header_size - sizeof (GimpPatternHeader), - NULL, NULL) == - ph.header_size - sizeof (GimpPatternHeader)) - { - guchar *plain_brush = brush_buf; - gint i; - - bh.bytes = 4; - brush_buf = g_malloc ((gsize) bh.width * bh.height * 4); - - for (i = 0; i < ph.width * ph.height; i++) - { - if (! g_input_stream_read_all (input, - brush_buf + i * 4, 3, - &bytes_read, NULL, error) || - bytes_read != 3) - { - g_object_unref (input); - g_free (name); - g_free (plain_brush); - g_free (brush_buf); - return -1; - } - - brush_buf[i * 4 + 3] = plain_brush[i]; - } - - g_free (plain_brush); - } - } - } - break; - - case 2: - { - guint16 *buf = (guint16 *) brush_buf; - - for (i = 0; i < bh.width * bh.height; i++, buf++) - { - union - { - guint16 u[2]; - gfloat f; - } short_float; - -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - short_float.u[0] = 0; - short_float.u[1] = GUINT16_FROM_BE (*buf); -#else - short_float.u[0] = GUINT16_FROM_BE (*buf); - short_float.u[1] = 0; -#endif - - brush_buf[i] = (guchar) (short_float.f * 255.0 + 0.5); - } - - bh.bytes = 1; - } - break; - - default: - break; - } - - /* - * Create a new image of the proper size and - * associate the filename with it. - */ - - switch (bh.bytes) - { - case 1: - base_type = GIMP_GRAY; - image_type = GIMP_GRAY_IMAGE; - format = babl_format ("Y' u8"); - break; - - case 4: - base_type = GIMP_RGB; - image_type = GIMP_RGBA_IMAGE; - format = babl_format ("R'G'B'A u8"); - break; - - default: - g_message ("Unsupported brush depth: %d\n" - "GIMP Brushes must be GRAY or RGBA\n", - bh.bytes); - g_free (name); - return -1; - } - - image_ID = gimp_image_new (bh.width, bh.height, base_type); - gimp_image_set_filename (image_ID, g_file_get_uri (file)); - - parasite = gimp_parasite_new ("gimp-brush-name", - GIMP_PARASITE_PERSISTENT, - strlen (name) + 1, name); - gimp_image_attach_parasite (image_ID, parasite); - gimp_parasite_free (parasite); - - layer_ID = gimp_layer_new (image_ID, name, bh.width, bh.height, - image_type, - 100, - gimp_image_get_default_new_layer_mode (image_ID)); - gimp_image_insert_layer (image_ID, layer_ID, -1, 0); - - g_free (name); - - buffer = gimp_drawable_get_buffer (layer_ID); - - /* invert */ - if (image_type == GIMP_GRAY_IMAGE) - for (i = 0; i < bh.width * bh.height; i++) - brush_buf[i] = 255 - brush_buf[i]; - - gegl_buffer_set (buffer, GEGL_RECTANGLE (0, 0, bh.width, bh.height), 0, - format, brush_buf, GEGL_AUTO_ROWSTRIDE); - - g_free (brush_buf); - g_object_unref (buffer); - g_object_unref (input); - - gimp_progress_update (1.0); - - return image_ID; -} - static gboolean save_image (GFile *file, gint32 image_ID, diff --git a/po/POTFILES.in b/po/POTFILES.in index ac5f03a6ff..122592c1d4 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -278,6 +278,9 @@ app/file/file-remote.c app/file/file-save.c app/file/file-utils.c +app/file-data/file-data-gbr.c +app/file-data/file-data.c + app/gegl/gimp-babl.c app/gegl/gimp-gegl-enums.c