[gimp] plug-ins: Create wbmp plug-in
- From: Jehan <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] plug-ins: Create wbmp plug-in
- Date: Thu, 7 Jul 2022 19:23:36 +0000 (UTC)
commit d1fac7bfa916495943472dfb12b1dd33307c65e8
Author: ktoyle <ktoyle students kennesaw edu>
Date: Thu Jul 7 19:23:35 2022 +0000
plug-ins: Create wbmp plug-in
Added plug-in that would let the Gimp program to read WBPM image files.
See #2508 and !662.
plug-ins/common/Makefile.am | 20 +++
plug-ins/common/file-wbmp.c | 322 ++++++++++++++++++++++++++++++++++++++++++++
plug-ins/common/meson.build | 1 +
3 files changed, 343 insertions(+)
---
diff --git a/plug-ins/common/Makefile.am b/plug-ins/common/Makefile.am
index 30dc180126..85ae6be80a 100644
--- a/plug-ins/common/Makefile.am
+++ b/plug-ins/common/Makefile.am
@@ -94,6 +94,7 @@ file_raw_data_libexecdir = $(gimpplugindir)/plug-ins/file-raw-data
file_sunras_libexecdir = $(gimpplugindir)/plug-ins/file-sunras
file_svg_libexecdir = $(gimpplugindir)/plug-ins/file-svg
file_tga_libexecdir = $(gimpplugindir)/plug-ins/file-tga
+file_wbmp_libexecdir = $(gimpplugindir)/plug-ins/file-wbmp
file_wmf_libexecdir = $(gimpplugindir)/plug-ins/file-wmf
file_xbm_libexecdir = $(gimpplugindir)/plug-ins/file-xbm
file_xmc_libexecdir = $(gimpplugindir)/plug-ins/file-xmc
@@ -172,6 +173,7 @@ file_raw_data_libexec_PROGRAMS = file-raw-data
file_sunras_libexec_PROGRAMS = file-sunras
file_svg_libexec_PROGRAMS = file-svg
file_tga_libexec_PROGRAMS = file-tga
+file_wbmp_libexec_PROGRAMS = file-wbmp
file_wmf_libexec_PROGRAMS = $(FILE_WMF)
file_xbm_libexec_PROGRAMS = file-xbm
file_xmc_libexec_PROGRAMS = $(FILE_XMC)
@@ -1116,6 +1118,24 @@ file_tga_LDADD = \
$(INTLLIBS) \
$(file_tga_RC)
+file_wbmp_SOURCES = \
+ file-wbmp.c
+
+file_wbmp_LDADD = \
+ $(libgimpui) \
+ $(libgimpwidgets) \
+ $(libgimpmodule) \
+ $(libgimp) \
+ $(libgimpmath) \
+ $(libgimpconfig) \
+ $(libgimpcolor) \
+ $(libgimpbase) \
+ $(GTK_LIBS) \
+ $(GEGL_LIBS) \
+ $(RT_LIBS) \
+ $(INTLLIBS) \
+ $(file_wbmp_RC)
+
file_wmf_CFLAGS = $(WMF_CFLAGS)
file_wmf_SOURCES = \
diff --git a/plug-ins/common/file-wbmp.c b/plug-ins/common/file-wbmp.c
new file mode 100644
index 0000000000..2e8f278127
--- /dev/null
+++ b/plug-ins/common/file-wbmp.c
@@ -0,0 +1,322 @@
+/*
+ * 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 <https://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <errno.h>
+#include <string.h>
+
+#include <glib/gstdio.h>
+
+#include <libgimp/gimp.h>
+#include <libgimp/gimpui.h>
+
+#include "libgimp/stdplugins-intl.h"
+
+#define LOAD_PROC "file-wbmp-load"
+#define PLUG_IN_BINARY "file-wbmp"
+#define PLUG_IN_ROLE "gimp-file-wbmp"
+
+#define ReadOK(file,buffer,len) (fread(buffer, len, 1, file) != 0)
+
+typedef struct _Wbmp Wbmp;
+typedef struct _WbmpClass WbmpClass;
+
+struct _Wbmp
+{
+ GimpPlugIn parent_instance;
+};
+
+struct _WbmpClass
+{
+ GimpPlugInClass parent_class;
+};
+
+#define WBMP_TYPE (wbmp_get_type ())
+#define WBMP (obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), WBMP_TYPE, Wbmp))
+
+GType wbmp_get_type (void) G_GNUC_CONST;
+
+static GList * wbmp_query_procedures (GimpPlugIn *plug_in);
+static GimpProcedure * wbmp_create_procedure (GimpPlugIn *plug_in,
+ const gchar *name);
+
+static GimpValueArray * wbmp_load (GimpProcedure *procedure,
+ GimpRunMode run_mode,
+ GFile *file,
+ const GimpValueArray *args,
+ gpointer run_data);
+
+GimpImage * load_image (GFile *file,
+ GError **error);
+
+static GimpImage * read_image (FILE *fd,
+ GFile *file,
+ gint width,
+ gint height,
+ GError **error);
+
+G_DEFINE_TYPE (Wbmp, wbmp, GIMP_TYPE_PLUG_IN)
+
+GIMP_MAIN (WBMP_TYPE)
+DEFINE_STD_SET_I18N
+
+static void
+wbmp_class_init (WbmpClass *klass)
+{
+ GimpPlugInClass *plug_in_class = GIMP_PLUG_IN_CLASS (klass);
+
+ plug_in_class->query_procedures = wbmp_query_procedures;
+ plug_in_class->create_procedure = wbmp_create_procedure;
+ plug_in_class->set_i18n = STD_SET_I18N;
+}
+
+static void
+wbmp_init (Wbmp *wmp)
+{
+}
+
+static GList *
+wbmp_query_procedures (GimpPlugIn *plug_in)
+{
+ GList *list = NULL;
+
+ list = g_list_append (list, g_strdup (LOAD_PROC));
+
+ return list;
+}
+
+static GimpProcedure *
+wbmp_create_procedure (GimpPlugIn *plug_in,
+ const gchar *name)
+{
+ GimpProcedure *procedure = NULL;
+
+ if (! strcmp (name, LOAD_PROC))
+ {
+ procedure = gimp_load_procedure_new (plug_in, name,
+ GIMP_PDB_PROC_TYPE_PLUGIN,
+ wbmp_load, NULL, NULL);
+
+ gimp_procedure_set_menu_label (procedure, N_("Wireless BMP image"));
+
+ gimp_procedure_set_documentation (procedure,
+ "Loads files of Wireless BMP file format",
+ "Loads files of Wireless BMP file format",
+ name);
+ gimp_procedure_set_attribution (procedure,
+ "Kevin Toyle",
+ "Kevin Toyle",
+ "2022");
+
+ gimp_file_procedure_set_mime_types (GIMP_FILE_PROCEDURE (procedure),
+ "image/vnd.wap.wbmp");
+ gimp_file_procedure_set_extensions (GIMP_FILE_PROCEDURE (procedure),
+ "wbmp");
+ }
+
+ return procedure;
+}
+
+static GimpValueArray *
+wbmp_load (GimpProcedure *procedure,
+ GimpRunMode run_mode,
+ GFile *file,
+ const GimpValueArray *args,
+ gpointer run_data)
+{
+ GimpValueArray *return_vals;
+ GimpImage *image;
+ GError *error = NULL;
+
+ gegl_init (NULL, NULL);
+
+ image = load_image (file, &error);
+
+ if (! image)
+ return gimp_procedure_new_return_values (procedure,
+ GIMP_PDB_EXECUTION_ERROR,
+ error);
+
+ return_vals = gimp_procedure_new_return_values (procedure,
+ GIMP_PDB_SUCCESS,
+ NULL);
+
+ GIMP_VALUES_SET_IMAGE (return_vals, 1, image);
+
+ return return_vals;
+}
+
+GimpImage *
+load_image (GFile *file,
+ GError **error)
+{
+ FILE *fd;
+ GimpImage *image = NULL;
+ gint width = 0;
+ gint height = 0;
+ gint8 magic;
+ guchar value;
+
+ gimp_progress_init_printf (_("Opening '%s'"),
+ gimp_file_get_utf8_name (file));
+
+ fd = g_fopen (g_file_peek_path (file), "rb");
+
+ if (! fd)
+ {
+ g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
+ _("Could not open '%s' for reading: %s"),
+ gimp_file_get_utf8_name (file), g_strerror (errno));
+ goto out;
+ }
+
+ /* Checking the type field to make sure it is 0. */
+ if (! ReadOK (fd, &magic, 1) || magic != 0)
+ {
+ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+ _("'%s': Invalid WBMP type value"),
+ gimp_file_get_utf8_name (file));
+ goto out;
+ }
+
+ /* Checking the fixed header field to make sure it is 0 */
+ if (! ReadOK (fd, &magic, 1) || magic != 0)
+ {
+ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+ _("'%s': Unsupported WBMP fixed header value"),
+ gimp_file_get_utf8_name (file));
+ goto out;
+ }
+
+ /* The width and height are stored as uintvar values */
+ while (ReadOK (fd, &value, 1))
+ {
+ width = (width << 7) | (value & 0x7F);
+ if (value >> 7 != 1)
+ break;
+ }
+ while (ReadOK (fd, &value, 1))
+ {
+ height = (height << 7) | (value & 0x7F);
+ if (value >> 7 != 1)
+ break;
+ }
+
+ if (width <= 0 || height <= 0)
+ {
+ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+ _("'%s' is not a valid WBMP file"),
+ gimp_file_get_utf8_name (file));
+ goto out;
+ }
+
+ image = read_image (fd, file, width, height, error);
+
+out:
+ if (fd)
+ fclose (fd);
+
+ return image;
+}
+
+/* Code referenced from /plug-ins/file-bmp/bmp-load.c */
+static GimpImage *
+read_image (FILE *fd,
+ GFile *file,
+ gint width,
+ gint height,
+ GError **error)
+{
+ const guchar mono[6] = { 0, 0, 0, 255, 255, 255 };
+ guchar v;
+ gint xpos = 0;
+ gint ypos = 0;
+ GimpImage *image;
+ GimpLayer *layer;
+ GeglBuffer *buffer;
+ guchar *dest, *temp;
+ gint i, cur_progress, max_progress;
+
+ /* Make a new image in GIMP */
+ if ((width < 0) || (width > GIMP_MAX_IMAGE_SIZE))
+ {
+ g_message (_("Unsupported or invalid image width: %d"), width);
+ return NULL;
+ }
+
+ if ((height < 0) || (height > GIMP_MAX_IMAGE_SIZE))
+ {
+ g_message (_("Unsupported or invalid image height: %d"), height);
+ return NULL;
+ }
+
+ image = gimp_image_new (width, height, GIMP_INDEXED);
+ layer = gimp_layer_new (image, _("Background"), width, height,
+ GIMP_INDEXED_IMAGE, 100,
+ gimp_image_get_default_new_layer_mode (image));
+
+ gimp_image_set_file (image, file);
+ gimp_image_set_colormap (image, mono, 2);
+
+ gimp_image_insert_layer (image, layer, NULL, 0);
+
+ dest = g_malloc0 (width * height);
+
+ ypos = 0;
+
+ cur_progress = 0;
+ max_progress = height;
+
+ while (ReadOK (fd, &v, 1))
+ {
+ for (i = 1; (i <= 8) && (xpos < width); i++, xpos++)
+ {
+ temp = dest + (ypos * width) + xpos;
+ *temp = (v & (((1 << 1) - 1) << (8 - i))) >> (8 - i);
+ }
+
+ if (xpos == width)
+ {
+ if (ypos == height - 1)
+ break;
+
+ ypos++;
+ xpos = 0;
+
+ cur_progress++;
+ if ((cur_progress % 5) == 0)
+ gimp_progress_update ((gdouble) cur_progress / (gdouble) max_progress);
+ }
+
+ if (ypos > height - 1)
+ break;
+ }
+
+ buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (layer));
+
+ gegl_buffer_set (buffer, GEGL_RECTANGLE (0, 0, width, height), 0, NULL, dest,
+ GEGL_AUTO_ROWSTRIDE);
+
+ g_object_unref (buffer);
+
+ g_free (dest);
+
+ return image;
+}
+
diff --git a/plug-ins/common/meson.build b/plug-ins/common/meson.build
index 8a8f17bc5c..a2e50069ab 100644
--- a/plug-ins/common/meson.build
+++ b/plug-ins/common/meson.build
@@ -59,6 +59,7 @@ common_plugins_list = [
'deps': [ gtk3, gegl, rsvg, ],
},
{ 'name': 'file-tga', },
+ { 'name': 'file-wbmp', },
{ 'name': 'file-xbm', },
{ 'name': 'file-xwd', },
{ 'name': 'film', },
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]