[gimp/alxsa-load-icns] plug-ins: Add support for loading .icns files
- From: Alx Sa <sawyeralex src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/alxsa-load-icns] plug-ins: Add support for loading .icns files
- Date: Sat, 15 Oct 2022 17:02:02 +0000 (UTC)
commit a22cec24f22be936ce15399d6f8d0c492654b152
Author: Alx Sa <cmyk student gmail com>
Date: Sat Oct 15 14:12:02 2022 +0000
plug-ins: Add support for loading .icns files
This ports ICNS loading code from Brion Vibber's 2004 plug-in.
It extends support for ICNS files that contain PNG or JP2 format icons.
configure.ac | 1 +
plug-ins/Makefile.am | 1 +
plug-ins/file-icns/Makefile.am | 55 ++++
plug-ins/file-icns/file-icns-data.c | 373 ++++++++++++++++++++++
plug-ins/file-icns/file-icns-data.h | 39 +++
plug-ins/file-icns/file-icns-load.c | 621 ++++++++++++++++++++++++++++++++++++
plug-ins/file-icns/file-icns-load.h | 34 ++
plug-ins/file-icns/file-icns.c | 236 ++++++++++++++
plug-ins/file-icns/file-icns.h | 58 ++++
plug-ins/file-icns/meson.build | 31 ++
plug-ins/meson.build | 1 +
po-plug-ins/POTFILES.in | 2 +
12 files changed, 1452 insertions(+)
---
diff --git a/configure.ac b/configure.ac
index 231f6a173d..c803fd00a5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3091,6 +3091,7 @@ plug-ins/file-exr/Makefile
plug-ins/file-faxg3/Makefile
plug-ins/file-fits/Makefile
plug-ins/file-fli/Makefile
+plug-ins/file-icns/Makefile
plug-ins/file-ico/Makefile
plug-ins/file-jpeg/Makefile
plug-ins/file-psd/Makefile
diff --git a/plug-ins/Makefile.am b/plug-ins/Makefile.am
index 6384022430..06d5cabfeb 100644
--- a/plug-ins/Makefile.am
+++ b/plug-ins/Makefile.am
@@ -33,6 +33,7 @@ SUBDIRS = \
file-faxg3 \
file-fits \
file-fli \
+ file-icns \
file-ico \
file-jpeg \
file-psd \
diff --git a/plug-ins/file-icns/Makefile.am b/plug-ins/file-icns/Makefile.am
new file mode 100644
index 0000000000..5ece7f8f86
--- /dev/null
+++ b/plug-ins/file-icns/Makefile.am
@@ -0,0 +1,55 @@
+## Process this file with automake to produce Makefile.in
+
+libgimpui = $(top_builddir)/libgimp/libgimpui-$(GIMP_API_VERSION).la
+libgimpconfig = $(top_builddir)/libgimpconfig/libgimpconfig-$(GIMP_API_VERSION).la
+libgimpwidgets = $(top_builddir)/libgimpwidgets/libgimpwidgets-$(GIMP_API_VERSION).la
+libgimp = $(top_builddir)/libgimp/libgimp-$(GIMP_API_VERSION).la
+libgimpcolor = $(top_builddir)/libgimpcolor/libgimpcolor-$(GIMP_API_VERSION).la
+libgimpmath = $(top_builddir)/libgimpmath/libgimpmath-$(GIMP_API_VERSION).la
+libgimpbase = $(top_builddir)/libgimpbase/libgimpbase-$(GIMP_API_VERSION).la
+
+if OS_WIN32
+mwindows = -mwindows
+endif
+
+if HAVE_WINDRES
+include $(top_srcdir)/build/windows/gimprc-plug-ins.rule
+file_icns_RC = file-icns.rc.o
+endif
+
+AM_LDFLAGS = $(mwindows)
+
+libexecdir = $(gimpplugindir)/plug-ins/file-icns
+
+libexec_PROGRAMS = file-icns
+
+file_icns_CFLAGS = $(PNG_CFLAGS)
+
+file_icns_SOURCES = \
+ file-icns-data.c \
+ file-icns-data.h \
+ file-icns-load.c \
+ file-icns-load.h \
+ file-icns.c \
+ file-icns.h
+
+AM_CPPFLAGS = \
+ -I$(top_srcdir) \
+ $(GTK_CFLAGS) \
+ $(GEGL_CFLAGS) \
+ -I$(includedir)
+
+LDADD = \
+ $(libgimpui) \
+ $(libgimpwidgets) \
+ $(libgimpconfig) \
+ $(libgimp) \
+ $(libgimpcolor) \
+ $(libgimpmath) \
+ $(libgimpbase) \
+ $(GTK_LIBS) \
+ $(GEGL_LIBS) \
+ $(PNG_LIBS) \
+ $(RT_LIBS) \
+ $(INTLLIBS) \
+ $(file_icns_RC)
diff --git a/plug-ins/file-icns/file-icns-data.c b/plug-ins/file-icns/file-icns-data.c
new file mode 100644
index 0000000000..febb56ed4b
--- /dev/null
+++ b/plug-ins/file-icns/file-icns-data.c
@@ -0,0 +1,373 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995-1999 Spencer Kimball and Peter Mattis
+ *
+ * file-icns-data.c
+ * Copyright (C) 2004 Brion Vibber <brion pobox com>
+ *
+ * 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 <glib.h>
+#include "file-icns-data.h"
+
+/* Ported from Brion Vibber's icnsdata.c code, under the GPL license, version 3
+ * or any later version of the license */
+IconType iconTypes[] =
+{
+ /* 1-bit, no mask? */
+ {"SICN", 16, 16, 1, 0, FALSE},
+ {"ICON", 32, 32, 1, 0, FALSE},
+
+ /* 1-bit image and hitmask */
+ {"icm#", 12, 12, 1, "icm#", FALSE},
+ {"ics#", 16, 16, 1, "ics#", FALSE},
+ {"ICN#", 32, 32, 1, "ICN#", FALSE},
+ {"ich#", 48, 48, 1, "ich#", FALSE},
+
+ /* 4-bit. Use mask from binary. */
+ {"icm4", 12, 12, 4, "icm#", FALSE},
+ {"ics4", 16, 16, 4, "ics#", FALSE},
+ {"icl4", 32, 32, 4, "ICN#", FALSE},
+ {"ich4", 48, 48, 4, "ich#", FALSE},
+
+ /* 8-bit. Use mask from binary. */
+ {"icm8", 12, 12, 8, "icm#", FALSE},
+ {"ics8", 16, 16, 8, "ics#", FALSE},
+ {"icl8", 32, 32, 8, "ICN#", FALSE},
+ {"ich8", 48, 48, 8, "ich#", FALSE},
+
+ /* 32-bit color icons; separate 8-bit alpha */
+ {"is32", 16, 16, 32, "s8mk", FALSE},
+ {"il32", 32, 32, 32, "l8mk", FALSE},
+ {"ih32", 48, 48, 32, "h8mk", FALSE},
+ {"it32", 128, 128, 32, "t8mk", FALSE},
+
+ /* Post-MacOS 10.0 ICNS formats */
+ /* PNG, JPEG 2000, or 24-bit RGB */
+ {"icp4", 16, 16, 32, "N/A", TRUE},
+ {"icp5", 32, 32, 32, "N/A", TRUE},
+
+ /* PNG or JPEG 2000 */
+ {"icp6", 48, 48, 0, "N/A", TRUE},
+ {"ic07", 128, 128, 0, "N/A", TRUE},
+ {"ic08", 256, 256, 0, "N/A", TRUE},
+ {"ic09", 512, 512, 0, "N/A", TRUE},
+ {"sb24", 24, 24, 0, "N/A", TRUE},
+
+ /* PNG or JPEG 2000 (Retina) */
+ {"ic10", 1024, 1024, 0, "N/A", TRUE},
+ {"ic11", 32, 32, 0, "N/A", TRUE},
+ {"ic12", 64, 64, 0, "N/A", TRUE},
+ {"ic13", 256, 256, 0, "N/A", TRUE},
+ {"ic14", 512, 512, 0, "N/A", TRUE},
+ {"icsB", 36, 36, 0, "N/A", TRUE},
+ {"SB24", 48, 48, 0, "N/A", TRUE},
+
+ /* ARGB, PNG, or JPEG 2000 */
+ {"ic04", 16, 16, 0, "N/A", TRUE},
+ {"icsb", 18, 18, 0, "N/A", TRUE},
+
+ {0, 0, 0, 0, 0}
+};
+
+IconType maskTypes[] =
+{
+ /* 8-bit masks */
+ {"s8mk", 16, 16, 8, 0},
+ {"l8mk", 32, 32, 8, 0},
+ {"h8mk", 48, 48, 8, 0},
+ {"t8mk", 128, 128, 8, 0},
+
+ {0, 0, 0, 0, 0}
+};
+
+guchar icns_colormap_4[] =
+{
+ 0xFF, 0xFF, 0xFF,
+ 0xFC, 0xF3, 0x05,
+ 0xFF, 0x64, 0x02,
+ 0xDD, 0x08, 0x06,
+ 0xF2, 0x08, 0x84,
+ 0x46, 0x00, 0xA5,
+ 0x00, 0x00, 0xD4,
+ 0x02, 0xAB, 0xEA,
+ 0x1F, 0xB7, 0x14,
+ 0x00, 0x64, 0x11,
+ 0x56, 0x2C, 0x05,
+ 0x90, 0x71, 0x3A,
+ 0xC0, 0xC0, 0xC0,
+ 0x80, 0x80, 0x80,
+ 0x40, 0x40, 0x40,
+ 0x00, 0x00, 0x00
+};
+
+guchar icns_colormap_8[] =
+{
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xCC,
+ 0xFF, 0xFF, 0x99,
+ 0xFF, 0xFF, 0x66,
+ 0xFF, 0xFF, 0x33,
+ 0xFF, 0xFF, 0x00,
+ 0xFF, 0xCC, 0xFF,
+ 0xFF, 0xCC, 0xCC,
+ 0xFF, 0xCC, 0x99,
+ 0xFF, 0xCC, 0x66,
+ 0xFF, 0xCC, 0x33,
+ 0xFF, 0xCC, 0x00,
+ 0xFF, 0x99, 0xFF,
+ 0xFF, 0x99, 0xCC,
+ 0xFF, 0x99, 0x99,
+ 0xFF, 0x99, 0x66,
+ 0xFF, 0x99, 0x33,
+ 0xFF, 0x99, 0x00,
+ 0xFF, 0x66, 0xFF,
+ 0xFF, 0x66, 0xCC,
+ 0xFF, 0x66, 0x99,
+ 0xFF, 0x66, 0x66,
+ 0xFF, 0x66, 0x33,
+ 0xFF, 0x66, 0x00,
+ 0xFF, 0x33, 0xFF,
+ 0xFF, 0x33, 0xCC,
+ 0xFF, 0x33, 0x99,
+ 0xFF, 0x33, 0x66,
+ 0xFF, 0x33, 0x33,
+ 0xFF, 0x33, 0x00,
+ 0xFF, 0x00, 0xFF,
+ 0xFF, 0x00, 0xCC,
+ 0xFF, 0x00, 0x99,
+ 0xFF, 0x00, 0x66,
+ 0xFF, 0x00, 0x33,
+ 0xFF, 0x00, 0x00,
+ 0xCC, 0xFF, 0xFF,
+ 0xCC, 0xFF, 0xCC,
+ 0xCC, 0xFF, 0x99,
+ 0xCC, 0xFF, 0x66,
+ 0xCC, 0xFF, 0x33,
+ 0xCC, 0xFF, 0x00,
+ 0xCC, 0xCC, 0xFF,
+ 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0x99,
+ 0xCC, 0xCC, 0x66,
+ 0xCC, 0xCC, 0x33,
+ 0xCC, 0xCC, 0x00,
+ 0xCC, 0x99, 0xFF,
+ 0xCC, 0x99, 0xCC,
+ 0xCC, 0x99, 0x99,
+ 0xCC, 0x99, 0x66,
+ 0xCC, 0x99, 0x33,
+ 0xCC, 0x99, 0x00,
+ 0xCC, 0x66, 0xFF,
+ 0xCC, 0x66, 0xCC,
+ 0xCC, 0x66, 0x99,
+ 0xCC, 0x66, 0x66,
+ 0xCC, 0x66, 0x33,
+ 0xCC, 0x66, 0x00,
+ 0xCC, 0x33, 0xFF,
+ 0xCC, 0x33, 0xCC,
+ 0xCC, 0x33, 0x99,
+ 0xCC, 0x33, 0x66,
+ 0xCC, 0x33, 0x33,
+ 0xCC, 0x33, 0x00,
+ 0xCC, 0x00, 0xFF,
+ 0xCC, 0x00, 0xCC,
+ 0xCC, 0x00, 0x99,
+ 0xCC, 0x00, 0x66,
+ 0xCC, 0x00, 0x33,
+ 0xCC, 0x00, 0x00,
+ 0x99, 0xFF, 0xFF,
+ 0x99, 0xFF, 0xCC,
+ 0x99, 0xFF, 0x99,
+ 0x99, 0xFF, 0x66,
+ 0x99, 0xFF, 0x33,
+ 0x99, 0xFF, 0x00,
+ 0x99, 0xCC, 0xFF,
+ 0x99, 0xCC, 0xCC,
+ 0x99, 0xCC, 0x99,
+ 0x99, 0xCC, 0x66,
+ 0x99, 0xCC, 0x33,
+ 0x99, 0xCC, 0x00,
+ 0x99, 0x99, 0xFF,
+ 0x99, 0x99, 0xCC,
+ 0x99, 0x99, 0x99,
+ 0x99, 0x99, 0x66,
+ 0x99, 0x99, 0x33,
+ 0x99, 0x99, 0x00,
+ 0x99, 0x66, 0xFF,
+ 0x99, 0x66, 0xCC,
+ 0x99, 0x66, 0x99,
+ 0x99, 0x66, 0x66,
+ 0x99, 0x66, 0x33,
+ 0x99, 0x66, 0x00,
+ 0x99, 0x33, 0xFF,
+ 0x99, 0x33, 0xCC,
+ 0x99, 0x33, 0x99,
+ 0x99, 0x33, 0x66,
+ 0x99, 0x33, 0x33,
+ 0x99, 0x33, 0x00,
+ 0x99, 0x00, 0xFF,
+ 0x99, 0x00, 0xCC,
+ 0x99, 0x00, 0x99,
+ 0x99, 0x00, 0x66,
+ 0x99, 0x00, 0x33,
+ 0x99, 0x00, 0x00,
+ 0x66, 0xFF, 0xFF,
+ 0x66, 0xFF, 0xCC,
+ 0x66, 0xFF, 0x99,
+ 0x66, 0xFF, 0x66,
+ 0x66, 0xFF, 0x33,
+ 0x66, 0xFF, 0x00,
+ 0x66, 0xCC, 0xFF,
+ 0x66, 0xCC, 0xCC,
+ 0x66, 0xCC, 0x99,
+ 0x66, 0xCC, 0x66,
+ 0x66, 0xCC, 0x33,
+ 0x66, 0xCC, 0x00,
+ 0x66, 0x99, 0xFF,
+ 0x66, 0x99, 0xCC,
+ 0x66, 0x99, 0x99,
+ 0x66, 0x99, 0x66,
+ 0x66, 0x99, 0x33,
+ 0x66, 0x99, 0x00,
+ 0x66, 0x66, 0xFF,
+ 0x66, 0x66, 0xCC,
+ 0x66, 0x66, 0x99,
+ 0x66, 0x66, 0x66,
+ 0x66, 0x66, 0x33,
+ 0x66, 0x66, 0x00,
+ 0x66, 0x33, 0xFF,
+ 0x66, 0x33, 0xCC,
+ 0x66, 0x33, 0x99,
+ 0x66, 0x33, 0x66,
+ 0x66, 0x33, 0x33,
+ 0x66, 0x33, 0x00,
+ 0x66, 0x00, 0xFF,
+ 0x66, 0x00, 0xCC,
+ 0x66, 0x00, 0x99,
+ 0x66, 0x00, 0x66,
+ 0x66, 0x00, 0x33,
+ 0x66, 0x00, 0x00,
+ 0x33, 0xFF, 0xFF,
+ 0x33, 0xFF, 0xCC,
+ 0x33, 0xFF, 0x99,
+ 0x33, 0xFF, 0x66,
+ 0x33, 0xFF, 0x33,
+ 0x33, 0xFF, 0x00,
+ 0x33, 0xCC, 0xFF,
+ 0x33, 0xCC, 0xCC,
+ 0x33, 0xCC, 0x99,
+ 0x33, 0xCC, 0x66,
+ 0x33, 0xCC, 0x33,
+ 0x33, 0xCC, 0x00,
+ 0x33, 0x99, 0xFF,
+ 0x33, 0x99, 0xCC,
+ 0x33, 0x99, 0x99,
+ 0x33, 0x99, 0x66,
+ 0x33, 0x99, 0x33,
+ 0x33, 0x99, 0x00,
+ 0x33, 0x66, 0xFF,
+ 0x33, 0x66, 0xCC,
+ 0x33, 0x66, 0x99,
+ 0x33, 0x66, 0x66,
+ 0x33, 0x66, 0x33,
+ 0x33, 0x66, 0x00,
+ 0x33, 0x33, 0xFF,
+ 0x33, 0x33, 0xCC,
+ 0x33, 0x33, 0x99,
+ 0x33, 0x33, 0x66,
+ 0x33, 0x33, 0x33,
+ 0x33, 0x33, 0x00,
+ 0x33, 0x00, 0xFF,
+ 0x33, 0x00, 0xCC,
+ 0x33, 0x00, 0x99,
+ 0x33, 0x00, 0x66,
+ 0x33, 0x00, 0x33,
+ 0x33, 0x00, 0x00,
+ 0x00, 0xFF, 0xFF,
+ 0x00, 0xFF, 0xCC,
+ 0x00, 0xFF, 0x99,
+ 0x00, 0xFF, 0x66,
+ 0x00, 0xFF, 0x33,
+ 0x00, 0xFF, 0x00,
+ 0x00, 0xCC, 0xFF,
+ 0x00, 0xCC, 0xCC,
+ 0x00, 0xCC, 0x99,
+ 0x00, 0xCC, 0x66,
+ 0x00, 0xCC, 0x33,
+ 0x00, 0xCC, 0x00,
+ 0x00, 0x99, 0xFF,
+ 0x00, 0x99, 0xCC,
+ 0x00, 0x99, 0x99,
+ 0x00, 0x99, 0x66,
+ 0x00, 0x99, 0x33,
+ 0x00, 0x99, 0x00,
+ 0x00, 0x66, 0xFF,
+ 0x00, 0x66, 0xCC,
+ 0x00, 0x66, 0x99,
+ 0x00, 0x66, 0x66,
+ 0x00, 0x66, 0x33,
+ 0x00, 0x66, 0x00,
+ 0x00, 0x33, 0xFF,
+ 0x00, 0x33, 0xCC,
+ 0x00, 0x33, 0x99,
+ 0x00, 0x33, 0x66,
+ 0x00, 0x33, 0x33,
+ 0x00, 0x33, 0x00,
+ 0x00, 0x00, 0xFF,
+ 0x00, 0x00, 0xCC,
+ 0x00, 0x00, 0x99,
+ 0x00, 0x00, 0x66,
+ 0x00, 0x00, 0x33,
+ 0xEE, 0x00, 0x00,
+ 0xDD, 0x00, 0x00,
+ 0xBB, 0x00, 0x00,
+ 0xAA, 0x00, 0x00,
+ 0x88, 0x00, 0x00,
+ 0x77, 0x00, 0x00,
+ 0x55, 0x00, 0x00,
+ 0x44, 0x00, 0x00,
+ 0x22, 0x00, 0x00,
+ 0x11, 0x00, 0x00,
+ 0x00, 0xEE, 0x00,
+ 0x00, 0xDD, 0x00,
+ 0x00, 0xBB, 0x00,
+ 0x00, 0xAA, 0x00,
+ 0x00, 0x88, 0x00,
+ 0x00, 0x77, 0x00,
+ 0x00, 0x55, 0x00,
+ 0x00, 0x44, 0x00,
+ 0x00, 0x22, 0x00,
+ 0x00, 0x11, 0x00,
+ 0x00, 0x00, 0xEE,
+ 0x00, 0x00, 0xDD,
+ 0x00, 0x00, 0xBB,
+ 0x00, 0x00, 0xAA,
+ 0x00, 0x00, 0x88,
+ 0x00, 0x00, 0x77,
+ 0x00, 0x00, 0x55,
+ 0x00, 0x00, 0x44,
+ 0x00, 0x00, 0x22,
+ 0x00, 0x00, 0x11,
+ 0xEE, 0xEE, 0xEE,
+ 0xDD, 0xDD, 0xDD,
+ 0xBB, 0xBB, 0xBB,
+ 0xAA, 0xAA, 0xAA,
+ 0x88, 0x88, 0x88,
+ 0x77, 0x77, 0x77,
+ 0x55, 0x55, 0x55,
+ 0x44, 0x44, 0x44,
+ 0x22, 0x22, 0x22,
+ 0x11, 0x11, 0x11,
+ 0x00, 0x00, 0x00
+};
diff --git a/plug-ins/file-icns/file-icns-data.h b/plug-ins/file-icns/file-icns-data.h
new file mode 100644
index 0000000000..705bed33f1
--- /dev/null
+++ b/plug-ins/file-icns/file-icns-data.h
@@ -0,0 +1,39 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995-1999 Spencer Kimball and Peter Mattis
+ *
+ * file-icns-data.h
+ * Copyright (C) 2004 Brion Vibber <brion pobox com>
+ *
+ * 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/>.
+ */
+
+#ifndef _ICNS_DATA_H
+#define _ICNS_DATA_H
+
+typedef struct _IconType
+{
+ gchar *type;
+ guint width;
+ guint height;
+ guint bits;
+ gchar *mask;
+ gboolean isModern; /* OSX icns files */
+} IconType;
+
+extern IconType iconTypes[];
+extern IconType maskTypes[];
+extern guchar icns_colormap_4[];
+extern guchar icns_colormap_8[];
+
+#endif
diff --git a/plug-ins/file-icns/file-icns-load.c b/plug-ins/file-icns/file-icns-load.c
new file mode 100644
index 0000000000..67e775cb49
--- /dev/null
+++ b/plug-ins/file-icns/file-icns-load.c
@@ -0,0 +1,621 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995-1999 Spencer Kimball and Peter Mattis
+ *
+ * file-icns-load.c
+ * Copyright (C) 2004 Brion Vibber <brion pobox com>
+ *
+ * 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 <png.h>
+
+/* #define ICNS_DBG */
+
+#include "file-icns.h"
+#include "file-icns-data.h"
+#include "file-icns-load.h"
+
+#include "libgimp/stdplugins-intl.h"
+
+IcnsResource * resource_load (FILE *file);
+
+IcnsResource * resource_find (IcnsResource *list,
+ gchar *type,
+ gint max);
+
+gboolean resource_get_next (IcnsResource *icns,
+ IcnsResource *res);
+
+void icns_slurp (guchar *dest,
+ IconType *icontype,
+ IcnsResource *icns,
+ IcnsResource *mask);
+
+gboolean icns_decompress (guchar *dest,
+ IconType *icontype,
+ IcnsResource *image,
+ IcnsResource *mask);
+
+void icns_attach_image (GimpImage *image,
+ IconType *icontype,
+ IcnsResource *icns,
+ IcnsResource *mask,
+ gboolean isOSX);
+
+GimpImage * icns_load (IcnsResource *icns,
+ GFile *file);
+
+/* Ported from Brion Vibber's icnsload.c code, under the GPL license, version 3
+ * or any later version of the license */
+IcnsResource *
+resource_load (FILE *file)
+{
+ IcnsResource *res = NULL;
+
+ if (file)
+ {
+ IcnsResourceHeader header;
+
+ if (1 == fread (&header, sizeof (IcnsResourceHeader), 1, file))
+ {
+ gchar type[5];
+ guint32 size;
+
+ strncpy (type, header.type, 4);
+ type[4] = '\0';
+ size = GUINT32_FROM_BE (header.size);
+
+ if (! strncmp (header.type, "icns", 4) && size > sizeof (IcnsResourceHeader))
+ {
+ res = (IcnsResource *) g_new (guchar, sizeof (IcnsResource) + size);
+ strncpy (res->type, header.type, 4);
+ res->type[4] = '\0';
+ res->size = size;
+ res->cursor = sizeof (IcnsResourceHeader);
+ res->data = (guchar *) res + sizeof (IcnsResource);
+ fseek (file, 0, SEEK_SET);
+
+ if (size != fread (res->data, 1, res->size, file))
+ {
+ g_message ("** expected %d bytes\n", size);
+ g_free (res);
+ res = NULL;
+ }
+ }
+ }
+ else
+ {
+ g_message (("** couldn't read icns header.\n"));
+ }
+ fclose (file);
+ }
+ else
+ {
+ g_message (("** couldn't open file.\n"));
+ }
+ return res;
+}
+
+IcnsResource *
+resource_find (IcnsResource *list,
+ gchar *type,
+ gint max)
+{
+ for (gint i = 0; i < max; i++)
+ {
+ if (! strncmp (list[i].type, type, 4))
+ return &list[i];
+ }
+ return NULL;
+}
+
+gboolean
+resource_get_next (IcnsResource *icns,
+ IcnsResource *res)
+{
+ IcnsResourceHeader *header;
+
+ if (icns->size - icns->cursor < sizeof (IcnsResourceHeader))
+ return FALSE;
+
+ header = (IcnsResourceHeader *) &(icns->data[icns->cursor]);
+ strncpy (res->type, header->type, 4);
+ res->size = GUINT32_FROM_BE (header->size);
+ res->cursor = sizeof (IcnsResourceHeader);
+ res->data = &(icns->data[icns->cursor]);
+
+ icns->cursor += res->size;
+ if (icns->cursor > icns->size)
+ {
+ gchar typestring[5];
+ fourcc_get_string (icns->type, typestring);
+ g_message ("icns resource_get_next: resource too big! type '%s', size %u\n",
+ typestring, icns->size);
+
+ return FALSE;
+ }
+ return TRUE;
+}
+
+GimpImage *
+icns_load (IcnsResource *icns,
+ GFile *file)
+{
+ IcnsResource *resources;
+ guint nResources;
+ gfloat current_resources = 0;
+ GimpImage *image;
+
+ resources = g_new (IcnsResource, 256);
+
+ /* Largest .icns icon is 1024 x 1024 */
+ image = gimp_image_new (1024, 1024, GIMP_RGB);
+ gimp_image_set_file (image, file);
+
+ nResources = 0;
+ while (resource_get_next (icns, &resources[nResources++])) {}
+
+ for (gint i = 0; iconTypes[i].type; i++)
+ {
+ IcnsResource *icns;
+ IcnsResource *mask = NULL;
+
+ if ((icns = resource_find (resources, iconTypes[i].type, nResources)))
+ {
+ if (! iconTypes[i].isModern)
+ mask = resource_find (resources, iconTypes[i].mask, nResources);
+
+ icns_attach_image (image, &iconTypes[i], icns, mask, iconTypes[i].isModern);
+
+ gimp_progress_update (current_resources++ / nResources);
+ }
+ }
+
+ gimp_image_resize_to_layers (image);
+ g_free (resources);
+ return image;
+}
+
+void
+icns_slurp (guchar *dest,
+ IconType *icontype,
+ IcnsResource *icns,
+ IcnsResource *mask)
+{
+ guint out;
+ guint max;
+ guchar bucket = 0;
+ guchar bit;
+ guint index;
+
+ max = icontype->width * icontype->height;
+ icns->cursor = sizeof (IcnsResourceHeader);
+
+ switch (icontype->bits)
+ {
+ case 1:
+ for (out = 0; out < max; out++)
+ {
+ if (out % 8 == 0)
+ bucket = icns->data[icns->cursor++];
+
+ bit = (bucket & 0x80) ? 0 : 255;
+ bucket = bucket << 1;
+ dest[out * 4] = bit;
+ dest[out * 4 + 1] = bit;
+ dest[out * 4 + 2] = bit;
+ }
+ break;
+ case 4:
+ for (out = 0; out < max; out++)
+ {
+ if (out % 2 == 0)
+ bucket = icns->data[icns->cursor++];
+
+ index = 3 * (bucket & 0xf0) >> 4;
+ bucket = bucket << 4;
+ dest[out * 4] = icns_colormap_4[index];
+ dest[out * 4 + 1] = icns_colormap_4[index + 1];
+ dest[out * 4 + 2] = icns_colormap_4[index + 2];
+ }
+ break;
+ case 8:
+ for (out = 0; out < max; out++)
+ {
+ index = 3 * icns->data[icns->cursor++];
+ dest[out * 4] = icns_colormap_8[index];
+ dest[out * 4 + 1] = icns_colormap_8[index + 1];
+ dest[out * 4 + 2] = icns_colormap_8[index + 2];
+ dest[out * 4 + 3] = 255;
+ }
+ break;
+ case 32:
+ for (out = 0; out < max; out++)
+ {
+ dest[out * 4] = icns->data[icns->cursor++];
+ dest[out * 4 + 1] = icns->data[icns->cursor++];
+ dest[out * 4 + 2] = icns->data[icns->cursor++];
+ /* Throw away alpha, use the mask */
+ icns->cursor++;
+ if (mask)
+ dest[out * 4 + 3] = icns->data[mask->cursor++];
+ else
+ dest[out * 4 + 3] = 255;
+ }
+ break;
+ }
+
+ /* Now for the mask */
+ if (mask && icontype->bits != 32)
+ {
+ mask->cursor = sizeof (IcnsResourceHeader) + icontype->width * icontype->height / 8;
+ for (out = 0; out < max; out++)
+ {
+ if (out % 8 == 0)
+ bucket = mask->data[mask->cursor++];
+
+ bit = (bucket & 0x80) ? 255 : 0;
+ bucket = bucket << 1;
+ dest[out * 4 + 3] = bit;
+ }
+ }
+}
+
+gboolean
+icns_decompress (guchar *dest,
+ IconType *icontype,
+ IcnsResource *image,
+ IcnsResource *mask)
+{
+ guint max;
+ guint channel;
+ guint out;
+ guchar run;
+ guchar val;
+ gint n_channels = 3;
+
+ max = icontype->width * icontype->height;
+ memset (dest, 255, max * 4);
+
+ /* For some reason there seem to be 4 null bytes at the start of an it32. */
+ if (! strncmp (icontype->type, "it32", 4))
+ image->cursor += 4;
+
+ for (channel = 0; channel < n_channels; channel++)
+ {
+ out = 0;
+ while (out < max)
+ {
+ run = image->data[image->cursor++];
+
+ if (run & 0x80)
+ {
+ /* Compressed */
+ if (image->cursor >= image->size)
+ {
+ g_message ("Corrupt icon: compressed run overflows input size.");
+ return FALSE;
+ }
+
+ val = image->data[image->cursor++];
+
+ for (run -= 125; run > 0; run--)
+ {
+ if (out >= max)
+ {
+ g_message ("Corrupt icon? compressed run overflows output size.");
+ return FALSE;
+ }
+ dest[out++ * 4 + channel] = val;
+ }
+ }
+ else
+ {
+ /* Uncompressed */
+ for (run += 1; run > 0; run--)
+ {
+ if (image->cursor >= image->size)
+ {
+ g_message ("Corrupt icon: uncompressed run overflows input size.");
+ return FALSE;
+ }
+ if (out >= max)
+ {
+ g_message ("Corrupt icon: uncompressed run overflows output size.");
+ return FALSE;
+ }
+ dest[out++ * 4 + channel] = image->data[image->cursor++];
+ }
+ }
+ }
+ }
+
+ if (mask)
+ {
+ gchar typestring[5];
+ fourcc_get_string (mask->type, typestring);
+
+ for (out = 0; out < max; out++)
+ dest[out * 4 + 3] = mask->data[mask->cursor++];
+ }
+ return TRUE;
+}
+
+void
+icns_attach_image (GimpImage *image,
+ IconType *icontype,
+ IcnsResource *icns,
+ IcnsResource *mask,
+ gboolean isOSX)
+{
+ gchar layer_name[5];
+ guchar *dest;
+ GimpLayer *layer;
+ GeglBuffer *buffer;
+ guint row;
+ guint expected_size;
+ gboolean layer_loaded = FALSE;
+
+ strncpy (layer_name, icontype->type, 4);
+ layer_name[4] = '\0';
+
+ row = 4 * icontype->width;
+ dest = g_malloc (row * icontype->height);
+
+ expected_size =
+ (icontype->width * icontype->height * icontype->bits) / 8;
+
+ if (icns == mask)
+ expected_size *= 2;
+
+ expected_size += sizeof (IcnsResourceHeader);
+
+ if (isOSX)
+ {
+ gchar image_type[5];
+ GimpImage *temp_image;
+ GFile *temp_file = NULL;
+ FILE *fp;
+ GimpValueArray *return_vals = NULL;
+ GimpLayer **layers;
+ GimpLayer *new_layer;
+ gint n_layers;
+ gchar *temp_file_type = NULL;
+ gchar *procedure_name = NULL;
+
+ temp_image = gimp_image_new (icontype->width, icontype->height,
+ gimp_image_get_base_type (image));
+
+ strncpy (image_type, (gchar *) icns->data + 8, 4);
+ image_type[4] = '\0';
+
+ /* PNG */
+ if (! strncmp (image_type, "\x89\x50\x4E\x47", 4))
+ {
+ temp_file_type = "png";
+ procedure_name = "file-png-load";
+ }
+ /* JPEG 2000 */
+ else if (! strncmp (image_type, "\x0CjP", 3))
+ {
+ temp_file_type = "jp2";
+ procedure_name = "file-jp2-load";
+ }
+
+ if (temp_file_type && procedure_name)
+ {
+ temp_file = gimp_temp_file (temp_file_type);
+ fp = g_fopen (g_file_peek_path (temp_file), "wb");
+
+ if (! fp)
+ {
+ g_message (_("Error trying to open temporary %s file '%s' "
+ "for icns loading: %s"),
+ temp_file_type,
+ gimp_file_get_utf8_name (temp_file),
+ g_strerror (errno));
+ return;
+ }
+
+ fwrite (icns->data + 8, sizeof (guchar), icns->size - 8, fp);
+ fclose (fp);
+
+ return_vals =
+ gimp_pdb_run_procedure (gimp_get_pdb (),
+ procedure_name,
+ GIMP_TYPE_RUN_MODE, GIMP_RUN_NONINTERACTIVE,
+ G_TYPE_FILE, temp_file,
+ G_TYPE_NONE);
+ }
+
+ if (temp_image && return_vals)
+ {
+ temp_image = g_value_get_object (gimp_value_array_index (return_vals, 1));
+
+ layers = gimp_image_get_layers (temp_image, &n_layers);
+ new_layer = gimp_layer_new_from_drawable (GIMP_DRAWABLE (layers[0]), image);
+ gimp_item_set_name (GIMP_ITEM (new_layer), layer_name);
+ gimp_image_insert_layer (image, new_layer, NULL, 0);
+
+ layer_loaded = TRUE;
+
+ g_file_delete (temp_file, NULL, NULL);
+ g_object_unref (temp_file);
+ gimp_value_array_unref (return_vals);
+ g_free (layers);
+ }
+ }
+ else
+ {
+ if (icontype->bits != 32 || expected_size == icns->size)
+ icns_slurp (dest, icontype, icns, mask);
+ else
+ icns_decompress (dest, icontype, icns, mask);
+ }
+
+ if (! layer_loaded)
+ {
+ layer = gimp_layer_new (image, layer_name, icontype->width, icontype->height,
+ GIMP_RGBA_IMAGE, 100,
+ gimp_image_get_default_new_layer_mode (image));
+
+ buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (layer));
+
+ gegl_buffer_set (buffer,
+ GEGL_RECTANGLE (0, 0, icontype->width, icontype->height),
+ 0, NULL,
+ dest, GEGL_AUTO_ROWSTRIDE);
+
+ gimp_image_insert_layer (image, layer, NULL, 0);
+
+ g_object_unref (buffer);
+ }
+
+ g_free (dest);
+}
+
+GimpImage *
+icns_load_image (GFile *file,
+ gint32 *file_offset,
+ GError **error)
+{
+ FILE *fp;
+ IcnsResource *icns;
+ GimpImage *image;
+
+ gegl_init (NULL, NULL);
+
+ gimp_progress_init_printf (_("Opening '%s'"),
+ gimp_file_get_utf8_name (file));
+
+ fp = g_fopen (g_file_peek_path (file), "rb");
+
+ if (! fp)
+ {
+ 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));
+ return NULL;
+ }
+
+ icns = resource_load (fp);
+
+ fclose (fp);
+
+ if (! icns)
+ {
+ g_message ("Invalid or corrupt icns resource file.");
+ return NULL;
+ }
+
+ image = icns_load (icns, file);
+
+ g_free (icns);
+
+ gimp_progress_update (1.0);
+
+ return image;
+}
+
+GimpImage *
+icns_load_thumbnail_image (GFile *file,
+ gint *width,
+ gint *height,
+ gint32 file_offset,
+ GError **error)
+{
+ gint w = 0;
+ FILE *fp;
+ GimpImage *image = NULL;
+ IcnsResource *icns;
+ IcnsResource *resources;
+ IcnsResource *mask = NULL;
+ guint i;
+ gint match = -1;
+ guint nResources = 0;
+
+ gegl_init (NULL, NULL);
+
+ gimp_progress_init_printf (_("Opening thumbnail for '%s'"),
+ gimp_file_get_utf8_name (file));
+
+ fp = g_fopen (g_file_peek_path (file), "rb");
+
+ if (! fp)
+ {
+ 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));
+ return NULL;
+ }
+
+ icns = resource_load (fp);
+ fclose (fp);
+
+ if (! icns)
+ {
+ g_message ("Invalid or corrupt icns resource file.");
+ return NULL;
+ }
+
+ image = gimp_image_new (1024, 1024, GIMP_RGB);
+
+ resources = g_new (IcnsResource, 256);
+ while (resource_get_next (icns, &resources[nResources++])) {}
+
+ for (i = 0; iconTypes[i].type; i++)
+ {
+ if ((icns = resource_find (resources, iconTypes[i].type, nResources)))
+ {
+ if (iconTypes[i].width > w)
+ {
+ w = iconTypes[i].width;
+ match = i;
+ }
+ }
+ }
+
+ if (match > -1)
+ {
+ icns = resource_find (resources, iconTypes[match].type, nResources);
+
+ if (! iconTypes[match].isModern)
+ mask = resource_find (resources, iconTypes[match].mask, nResources);
+
+ icns_attach_image (image, &iconTypes[match], icns, mask, iconTypes[match].isModern);
+
+ gimp_image_resize_to_layers (image);
+ }
+ else
+ {
+ g_message ("Invalid or corrupt icns resource file.");
+ return NULL;
+ }
+
+ g_free (resources);
+
+ gimp_progress_update (1.0);
+
+ return image;
+}
diff --git a/plug-ins/file-icns/file-icns-load.h b/plug-ins/file-icns/file-icns-load.h
new file mode 100644
index 0000000000..355fffd9ae
--- /dev/null
+++ b/plug-ins/file-icns/file-icns-load.h
@@ -0,0 +1,34 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995-1999 Spencer Kimball and Peter Mattis
+ *
+ * file-icns-load.h
+ * Copyright (C) 2004 Brion Vibber <brion pobox com>
+ *
+ * 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/>.
+ */
+
+#ifndef __ICNS_LOAD_H__
+#define __ICNS_LOAD_H__
+
+GimpImage * icns_load_image (GFile *file,
+ gint32 *file_offset,
+ GError **error);
+
+GimpImage * icns_load_thumbnail_image (GFile *file,
+ gint *width,
+ gint *height,
+ gint32 file_offset,
+ GError **error);
+
+#endif
diff --git a/plug-ins/file-icns/file-icns.c b/plug-ins/file-icns/file-icns.c
new file mode 100644
index 0000000000..78f9bcf78a
--- /dev/null
+++ b/plug-ins/file-icns/file-icns.c
@@ -0,0 +1,236 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995-1999 Spencer Kimball and Peter Mattis
+ *
+ * file-icns.c
+ * Copyright (C) 2004 Brion Vibber <brion pobox com>
+ *
+ * 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 <stdlib.h>
+#include <string.h>
+
+#include <glib/gstdio.h>
+
+#include <libgimp/gimp.h>
+#include <libgimp/gimpui.h>
+
+/* #define ICNS_DBG */
+
+#include "file-icns.h"
+#include "file-icns-load.h"
+//#include "ico-save.h"
+
+#include "libgimp/stdplugins-intl.h"
+
+#define LOAD_PROC "file-icns-load"
+#define LOAD_THUMB_PROC "file-icns-load-thumb"
+
+
+typedef struct _Icns Icns;
+typedef struct _IcnsClass IcnsClass;
+
+struct _Icns
+{
+ GimpPlugIn parent_instance;
+};
+
+struct _IcnsClass
+{
+ GimpPlugInClass parent_class;
+};
+
+
+#define ICNS_TYPE (icns_get_type ())
+#define ICNS (obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ICNS_TYPE, Icns))
+
+GType icns_get_type (void) G_GNUC_CONST;
+
+static GList * icns_query_procedures (GimpPlugIn *plug_in);
+static GimpProcedure * icns_create_procedure (GimpPlugIn *plug_in,
+ const gchar *name);
+
+static GimpValueArray * icns_load (GimpProcedure *procedure,
+ GimpRunMode run_mode,
+ GFile *file,
+ const GimpValueArray *args,
+ gpointer run_data);
+static GimpValueArray * icns_load_thumb (GimpProcedure *procedure,
+ GFile *file,
+ gint size,
+ const GimpValueArray *args,
+ gpointer run_data);
+
+
+G_DEFINE_TYPE (Icns, icns, GIMP_TYPE_PLUG_IN)
+
+GIMP_MAIN (ICNS_TYPE)
+DEFINE_STD_SET_I18N
+
+static void
+icns_class_init (IcnsClass *klass)
+{
+ GimpPlugInClass *plug_in_class = GIMP_PLUG_IN_CLASS (klass);
+
+ plug_in_class->query_procedures = icns_query_procedures;
+ plug_in_class->create_procedure = icns_create_procedure;
+ plug_in_class->set_i18n = STD_SET_I18N;
+}
+
+static void
+icns_init (Icns *icns)
+{
+}
+
+static GList *
+icns_query_procedures (GimpPlugIn *plug_in)
+{
+ GList *list = NULL;
+
+ list = g_list_append (list, g_strdup (LOAD_THUMB_PROC));
+ list = g_list_append (list, g_strdup (LOAD_PROC));
+
+ return list;
+}
+
+static GimpProcedure *
+icns_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,
+ icns_load, NULL, NULL);
+
+ gimp_procedure_set_menu_label (procedure, N_("Icns"));
+
+ gimp_procedure_set_documentation (procedure,
+ "Loads files in Apple Icon Image format",
+ "Loads Apple Icon Image files.",
+ name);
+ gimp_procedure_set_attribution (procedure,
+ "Brion Vibber <brion pobox com>",
+ "Brion Vibber <brion pobox com>",
+ "2004");
+
+ gimp_file_procedure_set_mime_types (GIMP_FILE_PROCEDURE (procedure),
+ "image/x-icns");
+ gimp_file_procedure_set_extensions (GIMP_FILE_PROCEDURE (procedure),
+ "icns");
+ gimp_file_procedure_set_magics (GIMP_FILE_PROCEDURE (procedure),
+ "0,string,\x69\x63\x6E\x73");
+
+ gimp_load_procedure_set_thumbnail_loader (GIMP_LOAD_PROCEDURE (procedure),
+ LOAD_THUMB_PROC);
+ }
+ else if (! strcmp (name, LOAD_THUMB_PROC))
+ {
+ procedure = gimp_thumbnail_procedure_new (plug_in, name,
+ GIMP_PDB_PROC_TYPE_PLUGIN,
+ icns_load_thumb, NULL, NULL);
+
+ gimp_procedure_set_documentation (procedure,
+ "Loads a preview from an Apple Icon Image file",
+ "",
+ name);
+ gimp_procedure_set_attribution (procedure,
+ "Brion Vibber <brion pobox com>",
+ "Brion Vibber <brion pobox com>",
+ "2004");
+ }
+
+ return procedure;
+}
+
+static GimpValueArray *
+icns_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 = icns_load_image (file, NULL, &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;
+}
+
+static GimpValueArray *
+icns_load_thumb (GimpProcedure *procedure,
+ GFile *file,
+ gint size,
+ const GimpValueArray *args,
+ gpointer run_data)
+{
+ GimpValueArray *return_vals;
+ gint width;
+ gint height;
+ GimpImage *image;
+ GError *error = NULL;
+
+ gegl_init (NULL, NULL);
+
+ width = size;
+ height = size;
+
+ image = icns_load_thumbnail_image (file,
+ &width, &height, 0, &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);
+ GIMP_VALUES_SET_INT (return_vals, 2, width);
+ GIMP_VALUES_SET_INT (return_vals, 3, height);
+
+ gimp_value_array_truncate (return_vals, 4);
+
+ return return_vals;
+}
+
+/* Buffer should point to *at least 5 byte buffer*! */
+void
+fourcc_get_string (gchar *fourcc,
+ gchar *buf)
+{
+ buf = fourcc;
+ buf[4] = 0;
+}
diff --git a/plug-ins/file-icns/file-icns.h b/plug-ins/file-icns/file-icns.h
new file mode 100644
index 0000000000..872b73aa95
--- /dev/null
+++ b/plug-ins/file-icns/file-icns.h
@@ -0,0 +1,58 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995-1999 Spencer Kimball and Peter Mattis
+ *
+ * file-icns.h
+ * Copyright (C) 2004 Brion Vibber <brion pobox com>
+ *
+ * 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/>.
+ */
+
+#ifndef __ICNS_H__
+#define __ICNS_H__
+
+
+#ifdef ICNS_DBG
+#define D(x) \
+{ \
+ printf("ICNS plugin: "); \
+ printf x; \
+}
+#else
+#define D(x)
+#endif
+
+#define PLUG_IN_BINARY "file-icns"
+#define PLUG_IN_ROLE "gimp-file-icns"
+
+
+typedef struct _IcnsResourceHeader
+{
+ /* Big-endian! */
+ gchar type[4];
+ guint32 size;
+} IcnsResourceHeader;
+
+typedef struct _IcnsResource
+{
+ gchar type[5];
+ guint32 size;
+ guint32 cursor;
+ guchar *data;
+} IcnsResource;
+
+void
+fourcc_get_string (gchar *fourcc,
+ gchar *buf);
+
+#endif /* __ICNS_H__ */
diff --git a/plug-ins/file-icns/meson.build b/plug-ins/file-icns/meson.build
new file mode 100644
index 0000000000..a66b342021
--- /dev/null
+++ b/plug-ins/file-icns/meson.build
@@ -0,0 +1,31 @@
+plugin_name = 'file-icns'
+
+plugin_sources = [
+ 'file-icns-data.c',
+ 'file-icns-load.c',
+ 'file-icns.c',
+]
+
+if platform_windows
+ plugin_sources += windows.compile_resources(
+ gimp_plugins_rc,
+ args: [
+ '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
+ '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
+ '--define', 'TOP_SRCDIR="@0@"' .format(meson.source_root()),
+ ],
+ include_directories: [
+ rootInclude, appInclude,
+ ],
+ )
+endif
+
+executable(plugin_name,
+ plugin_sources,
+ dependencies: [
+ libgimpui_dep,
+ libpng,
+ ],
+ install: true,
+ install_dir: gimpplugindir / 'plug-ins' / plugin_name,
+)
diff --git a/plug-ins/meson.build b/plug-ins/meson.build
index 11c0553541..22556d618f 100644
--- a/plug-ins/meson.build
+++ b/plug-ins/meson.build
@@ -5,6 +5,7 @@ subdir('file-exr')
subdir('file-faxg3')
subdir('file-fits')
subdir('file-fli')
+subdir('file-icns')
subdir('file-ico')
subdir('file-jpeg')
subdir('file-psd')
diff --git a/po-plug-ins/POTFILES.in b/po-plug-ins/POTFILES.in
index eff90c9f92..4494e8a05c 100644
--- a/po-plug-ins/POTFILES.in
+++ b/po-plug-ins/POTFILES.in
@@ -96,6 +96,8 @@ plug-ins/file-faxg3/faxg3.c
plug-ins/file-fits/fits.c
plug-ins/file-fli/fli.c
plug-ins/file-fli/fli-gimp.c
+plug-ins/file-icns/file-icns-load.c
+plug-ins/file-icns/file-icns.c
plug-ins/file-ico/ico-dialog.c
plug-ins/file-ico/ico-load.c
plug-ins/file-ico/ico-save.c
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]