Initial checkin of Pika from heckimp
This commit is contained in:
431
app/file-data/file-data-gbr.c
Normal file
431
app/file-data/file-data-gbr.c
Normal file
@ -0,0 +1,431 @@
|
||||
/* PIKA - Photo and Image Kooker Application
|
||||
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
|
||||
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
|
||||
*
|
||||
* Original copyright, applying to most contents (license remains unchanged):
|
||||
* 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 <cairo.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include <gegl.h>
|
||||
|
||||
#include "libpikabase/pikabase.h"
|
||||
#include "libpikacolor/pikacolor.h"
|
||||
#include "libpikaconfig/pikaconfig.h"
|
||||
|
||||
#include "core/core-types.h"
|
||||
|
||||
#include "core/pika.h"
|
||||
#include "core/pikabrush.h"
|
||||
#include "core/pikabrush-load.h"
|
||||
#include "core/pikabrush-private.h"
|
||||
#include "core/pikadrawable.h"
|
||||
#include "core/pikaimage.h"
|
||||
#include "core/pikalayer-new.h"
|
||||
#include "core/pikaimage-resize.h"
|
||||
#include "core/pikaparamspecs.h"
|
||||
#include "core/pikatempbuf.h"
|
||||
|
||||
#include "pdb/pikaprocedure.h"
|
||||
|
||||
#include "file-data-gbr.h"
|
||||
|
||||
#include "pika-intl.h"
|
||||
|
||||
|
||||
/* local function prototypes */
|
||||
|
||||
static PikaImage * file_gbr_brush_to_image (Pika *pika,
|
||||
PikaBrush *brush);
|
||||
static PikaBrush * file_gbr_image_to_brush (PikaImage *image,
|
||||
PikaDrawable *drawable,
|
||||
const gchar *name,
|
||||
gdouble spacing);
|
||||
|
||||
|
||||
/* public functions */
|
||||
|
||||
PikaValueArray *
|
||||
file_gbr_load_invoker (PikaProcedure *procedure,
|
||||
Pika *pika,
|
||||
PikaContext *context,
|
||||
PikaProgress *progress,
|
||||
const PikaValueArray *args,
|
||||
GError **error)
|
||||
{
|
||||
PikaValueArray *return_vals;
|
||||
PikaImage *image = NULL;
|
||||
GFile *file;
|
||||
GInputStream *input;
|
||||
GError *my_error = NULL;
|
||||
|
||||
pika_set_busy (pika);
|
||||
|
||||
file = g_value_get_object (pika_value_array_index (args, 1));
|
||||
|
||||
input = G_INPUT_STREAM (g_file_read (file, NULL, &my_error));
|
||||
|
||||
if (input)
|
||||
{
|
||||
PikaBrush *brush = pika_brush_load_brush (context, file, input, error);
|
||||
|
||||
if (brush)
|
||||
{
|
||||
image = file_gbr_brush_to_image (pika, brush);
|
||||
g_object_unref (brush);
|
||||
}
|
||||
|
||||
g_object_unref (input);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_propagate_prefixed_error (error, my_error,
|
||||
_("Could not open '%s' for reading: "),
|
||||
pika_file_get_utf8_name (file));
|
||||
}
|
||||
|
||||
return_vals = pika_procedure_get_return_values (procedure, image != NULL,
|
||||
error ? *error : NULL);
|
||||
|
||||
if (image)
|
||||
g_value_set_object (pika_value_array_index (return_vals, 1), image);
|
||||
|
||||
pika_unset_busy (pika);
|
||||
|
||||
return return_vals;
|
||||
}
|
||||
|
||||
PikaValueArray *
|
||||
file_gbr_save_invoker (PikaProcedure *procedure,
|
||||
Pika *pika,
|
||||
PikaContext *context,
|
||||
PikaProgress *progress,
|
||||
const PikaValueArray *args,
|
||||
GError **error)
|
||||
{
|
||||
PikaValueArray *return_vals;
|
||||
PikaImage *image;
|
||||
PikaDrawable *drawable;
|
||||
PikaBrush *brush;
|
||||
const gchar *name;
|
||||
GFile *file;
|
||||
gint spacing;
|
||||
gboolean success;
|
||||
|
||||
pika_set_busy (pika);
|
||||
|
||||
image = g_value_get_object (pika_value_array_index (args, 1));
|
||||
drawable = g_value_get_object (pika_value_array_index (args, 2));
|
||||
file = g_value_get_object (pika_value_array_index (args, 3));
|
||||
spacing = g_value_get_int (pika_value_array_index (args, 4));
|
||||
name = g_value_get_string (pika_value_array_index (args, 5));
|
||||
|
||||
brush = file_gbr_image_to_brush (image, drawable, name, spacing);
|
||||
|
||||
pika_data_set_file (PIKA_DATA (brush), file, TRUE, TRUE);
|
||||
|
||||
success = pika_data_save (PIKA_DATA (brush), error);
|
||||
|
||||
g_object_unref (brush);
|
||||
|
||||
return_vals = pika_procedure_get_return_values (procedure, success,
|
||||
error ? *error : NULL);
|
||||
|
||||
pika_unset_busy (pika);
|
||||
|
||||
return return_vals;
|
||||
}
|
||||
|
||||
PikaLayer *
|
||||
file_gbr_brush_to_layer (PikaImage *image,
|
||||
PikaBrush *brush)
|
||||
{
|
||||
PikaLayer *layer;
|
||||
const Babl *format;
|
||||
gboolean alpha;
|
||||
gint width;
|
||||
gint height;
|
||||
gint image_width;
|
||||
gint image_height;
|
||||
PikaTempBuf *mask;
|
||||
PikaTempBuf *pixmap;
|
||||
GeglBuffer *buffer;
|
||||
|
||||
g_return_val_if_fail (PIKA_IS_IMAGE (image), NULL);
|
||||
g_return_val_if_fail (PIKA_IS_BRUSH (brush), NULL);
|
||||
|
||||
mask = pika_brush_get_mask (brush);
|
||||
pixmap = pika_brush_get_pixmap (brush);
|
||||
|
||||
if (pixmap)
|
||||
alpha = TRUE;
|
||||
else
|
||||
alpha = FALSE;
|
||||
|
||||
width = pika_temp_buf_get_width (mask);
|
||||
height = pika_temp_buf_get_height (mask);
|
||||
|
||||
image_width = pika_image_get_width (image);
|
||||
image_height = pika_image_get_height (image);
|
||||
|
||||
if (width > image_width || height > image_height)
|
||||
{
|
||||
gint new_width = MAX (image_width, width);
|
||||
gint new_height = MAX (image_height, height);
|
||||
|
||||
pika_image_resize (image, pika_get_user_context (image->pika),
|
||||
new_width, new_height,
|
||||
(new_width - image_width) / 2,
|
||||
(new_height - image_height) / 2,
|
||||
NULL);
|
||||
|
||||
image_width = new_width;
|
||||
image_height = new_height;
|
||||
}
|
||||
|
||||
format = pika_image_get_layer_format (image, alpha);
|
||||
|
||||
layer = pika_layer_new (image, width, height, format,
|
||||
pika_object_get_name (brush),
|
||||
1.0, PIKA_LAYER_MODE_NORMAL);
|
||||
|
||||
pika_item_set_offset (PIKA_ITEM (layer),
|
||||
(image_width - width) / 2,
|
||||
(image_height - height) / 2);
|
||||
|
||||
buffer = pika_drawable_get_buffer (PIKA_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"),
|
||||
pika_temp_buf_get_data (pixmap), GEGL_AUTO_ROWSTRIDE);
|
||||
|
||||
pixmap_data = gegl_buffer_linear_open (buffer, NULL, NULL, NULL);
|
||||
mask_data = pika_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 = pika_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 layer;
|
||||
}
|
||||
|
||||
PikaBrush *
|
||||
file_gbr_drawable_to_brush (PikaDrawable *drawable,
|
||||
const GeglRectangle *rect,
|
||||
const gchar *name,
|
||||
gdouble spacing)
|
||||
{
|
||||
PikaBrush *brush;
|
||||
GeglBuffer *buffer;
|
||||
PikaTempBuf *mask;
|
||||
PikaTempBuf *pixmap = NULL;
|
||||
gint width;
|
||||
gint height;
|
||||
|
||||
g_return_val_if_fail (PIKA_IS_DRAWABLE (drawable), NULL);
|
||||
g_return_val_if_fail (rect != NULL, NULL);
|
||||
|
||||
buffer = pika_drawable_get_buffer (drawable);
|
||||
width = rect->width;
|
||||
height = rect->height;
|
||||
|
||||
brush = g_object_new (PIKA_TYPE_BRUSH,
|
||||
"name", name,
|
||||
"mime-type", "image/x-pika-gbr",
|
||||
"spacing", spacing,
|
||||
NULL);
|
||||
|
||||
mask = pika_temp_buf_new (width, height, babl_format ("Y u8"));
|
||||
|
||||
if (pika_drawable_is_gray (drawable))
|
||||
{
|
||||
guchar *m = pika_temp_buf_get_data (mask);
|
||||
gint i;
|
||||
|
||||
if (pika_drawable_has_alpha (drawable))
|
||||
{
|
||||
GeglBufferIterator *iter;
|
||||
PikaRGB white;
|
||||
|
||||
pika_rgba_set_uchar (&white, 255, 255, 255, 255);
|
||||
|
||||
iter = gegl_buffer_iterator_new (buffer, rect, 0,
|
||||
babl_format ("Y'A u8"),
|
||||
GEGL_ACCESS_READ, GEGL_ABYSS_NONE,
|
||||
1);
|
||||
|
||||
while (gegl_buffer_iterator_next (iter))
|
||||
{
|
||||
guint8 *data = (guint8 *) iter->items[0].data;
|
||||
gint j;
|
||||
|
||||
for (j = 0; j < iter->length; j++)
|
||||
{
|
||||
PikaRGB gray;
|
||||
gint x, y;
|
||||
gint dest;
|
||||
|
||||
pika_rgba_set_uchar (&gray,
|
||||
data[0], data[0], data[0],
|
||||
data[1]);
|
||||
|
||||
pika_rgb_composite (&gray, &white,
|
||||
PIKA_RGB_COMPOSITE_BEHIND);
|
||||
|
||||
x = iter->items[0].roi.x + j % iter->items[0].roi.width;
|
||||
y = iter->items[0].roi.y + j / iter->items[0].roi.width;
|
||||
|
||||
dest = y * width + x;
|
||||
|
||||
pika_rgba_get_uchar (&gray, &m[dest], NULL, NULL, NULL);
|
||||
|
||||
data += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gegl_buffer_get (buffer, rect, 1.0,
|
||||
babl_format ("Y' u8"), m,
|
||||
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
|
||||
}
|
||||
|
||||
/* invert */
|
||||
for (i = 0; i < width * height; i++)
|
||||
m[i] = 255 - m[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
pixmap = pika_temp_buf_new (width, height, babl_format ("R'G'B' u8"));
|
||||
|
||||
gegl_buffer_get (buffer, rect, 1.0,
|
||||
babl_format ("R'G'B' u8"),
|
||||
pika_temp_buf_get_data (pixmap),
|
||||
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
|
||||
|
||||
gegl_buffer_get (buffer, rect, 1.0,
|
||||
babl_format ("A u8"),
|
||||
pika_temp_buf_get_data (mask),
|
||||
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
|
||||
}
|
||||
|
||||
|
||||
brush->priv->mask = mask;
|
||||
brush->priv->pixmap = pixmap;
|
||||
|
||||
return brush;
|
||||
}
|
||||
|
||||
|
||||
/* private functions */
|
||||
|
||||
static PikaImage *
|
||||
file_gbr_brush_to_image (Pika *pika,
|
||||
PikaBrush *brush)
|
||||
{
|
||||
PikaImage *image;
|
||||
PikaLayer *layer;
|
||||
PikaImageBaseType base_type;
|
||||
gint width;
|
||||
gint height;
|
||||
PikaTempBuf *mask = pika_brush_get_mask (brush);
|
||||
PikaTempBuf *pixmap = pika_brush_get_pixmap (brush);
|
||||
GString *string;
|
||||
PikaConfigWriter *writer;
|
||||
PikaParasite *parasite;
|
||||
|
||||
if (pixmap)
|
||||
base_type = PIKA_RGB;
|
||||
else
|
||||
base_type = PIKA_GRAY;
|
||||
|
||||
width = pika_temp_buf_get_width (mask);
|
||||
height = pika_temp_buf_get_height (mask);
|
||||
|
||||
image = pika_image_new (pika, width, height, base_type,
|
||||
PIKA_PRECISION_U8_NON_LINEAR);
|
||||
|
||||
string = g_string_new (NULL);
|
||||
writer = pika_config_writer_new_from_string (string);
|
||||
|
||||
pika_config_writer_open (writer, "spacing");
|
||||
pika_config_writer_printf (writer, "%d", pika_brush_get_spacing (brush));
|
||||
pika_config_writer_close (writer);
|
||||
|
||||
pika_config_writer_linefeed (writer);
|
||||
|
||||
pika_config_writer_open (writer, "description");
|
||||
pika_config_writer_string (writer, pika_object_get_name (brush));
|
||||
pika_config_writer_close (writer);
|
||||
|
||||
pika_config_writer_finish (writer, NULL, NULL);
|
||||
|
||||
parasite = pika_parasite_new ("PikaProcedureConfig-file-gbr-save-last",
|
||||
PIKA_PARASITE_PERSISTENT,
|
||||
string->len + 1, string->str);
|
||||
pika_image_parasite_attach (image, parasite, FALSE);
|
||||
pika_parasite_free (parasite);
|
||||
|
||||
g_string_free (string, TRUE);
|
||||
|
||||
layer = file_gbr_brush_to_layer (image, brush);
|
||||
pika_image_add_layer (image, layer, NULL, 0, FALSE);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
static PikaBrush *
|
||||
file_gbr_image_to_brush (PikaImage *image,
|
||||
PikaDrawable *drawable,
|
||||
const gchar *name,
|
||||
gdouble spacing)
|
||||
{
|
||||
gint width = pika_item_get_width (PIKA_ITEM (drawable));
|
||||
gint height = pika_item_get_height (PIKA_ITEM (drawable));
|
||||
|
||||
return file_gbr_drawable_to_brush (drawable,
|
||||
GEGL_RECTANGLE (0, 0, width, height),
|
||||
name, spacing);
|
||||
}
|
48
app/file-data/file-data-gbr.h
Normal file
48
app/file-data/file-data-gbr.h
Normal file
@ -0,0 +1,48 @@
|
||||
/* PIKA - Photo and Image Kooker Application
|
||||
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
|
||||
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
|
||||
*
|
||||
* Original copyright, applying to most contents (license remains unchanged):
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef __FILE_DATA_GBR_H__
|
||||
#define __FILE_DATA_GBR_H__
|
||||
|
||||
|
||||
PikaValueArray * file_gbr_load_invoker (PikaProcedure *procedure,
|
||||
Pika *pika,
|
||||
PikaContext *context,
|
||||
PikaProgress *progress,
|
||||
const PikaValueArray *args,
|
||||
GError **error);
|
||||
|
||||
PikaValueArray * file_gbr_save_invoker (PikaProcedure *procedure,
|
||||
Pika *pika,
|
||||
PikaContext *context,
|
||||
PikaProgress *progress,
|
||||
const PikaValueArray *args,
|
||||
GError **error);
|
||||
|
||||
PikaLayer * file_gbr_brush_to_layer (PikaImage *image,
|
||||
PikaBrush *brush);
|
||||
PikaBrush * file_gbr_drawable_to_brush (PikaDrawable *drawable,
|
||||
const GeglRectangle *rect,
|
||||
const gchar *name,
|
||||
gdouble spacing);
|
||||
|
||||
|
||||
#endif /* __FILE_DATA_GBR_H__ */
|
572
app/file-data/file-data-gex.c
Normal file
572
app/file-data/file-data-gex.c
Normal file
@ -0,0 +1,572 @@
|
||||
/* PIKA - Photo and Image Kooker Application
|
||||
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
|
||||
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
|
||||
*
|
||||
* Original copyright, applying to most contents (license remains unchanged):
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
* Copyright (C) 2019 Jehan
|
||||
*
|
||||
* 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 <appstream-glib.h>
|
||||
#include <archive.h>
|
||||
#include <archive_entry.h>
|
||||
#include <cairo.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include <gegl.h>
|
||||
#include <glib.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#include "libpikabase/pikabase.h"
|
||||
#include "libpikacolor/pikacolor.h"
|
||||
|
||||
#include "core/core-types.h"
|
||||
|
||||
#include "core/pika.h"
|
||||
#include "core/pikabrush.h"
|
||||
#include "core/pikabrush-load.h"
|
||||
#include "core/pikabrush-private.h"
|
||||
#include "core/pikadrawable.h"
|
||||
#include "core/pikaextension.h"
|
||||
#include "core/pikaextensionmanager.h"
|
||||
#include "core/pikaextension-error.h"
|
||||
#include "core/pikaimage.h"
|
||||
#include "core/pikalayer-new.h"
|
||||
#include "core/pikaparamspecs.h"
|
||||
#include "core/pikatempbuf.h"
|
||||
#include "core/pika-utils.h"
|
||||
|
||||
#include "pdb/pikaprocedure.h"
|
||||
|
||||
#include "file-data-gex.h"
|
||||
|
||||
#include "pika-intl.h"
|
||||
|
||||
|
||||
/* local function prototypes */
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GInputStream *input;
|
||||
void *buffer;
|
||||
} GexReadData;
|
||||
|
||||
static int file_gex_open_callback (struct archive *a,
|
||||
void *client_data);
|
||||
static la_ssize_t file_gex_read_callback (struct archive *a,
|
||||
void *client_data,
|
||||
const void **buffer);
|
||||
static int file_gex_close_callback (struct archive *a,
|
||||
void *client_data);
|
||||
|
||||
static gboolean file_gex_validate_path (const gchar *path,
|
||||
const gchar *file_name,
|
||||
gboolean first,
|
||||
gchar **plugin_id,
|
||||
GError **error);
|
||||
static gboolean file_gex_validate (GFile *file,
|
||||
AsApp **appstream,
|
||||
GError **error);
|
||||
static gchar * file_gex_decompress (GFile *file,
|
||||
gchar *plugin_id,
|
||||
GError **error);
|
||||
|
||||
static int
|
||||
file_gex_open_callback (struct archive *a,
|
||||
void *client_data)
|
||||
{
|
||||
/* File already opened when we start with libarchive. */
|
||||
GexReadData *data = client_data;
|
||||
|
||||
data->buffer = g_malloc0 (2048);
|
||||
|
||||
return ARCHIVE_OK;
|
||||
}
|
||||
|
||||
static la_ssize_t
|
||||
file_gex_read_callback (struct archive *a,
|
||||
void *client_data,
|
||||
const void **buffer)
|
||||
{
|
||||
GexReadData *data = client_data;
|
||||
GError *error = NULL;
|
||||
gssize read_count;
|
||||
|
||||
read_count = g_input_stream_read (data->input, data->buffer, 2048, NULL, &error);
|
||||
|
||||
if (read_count == -1)
|
||||
{
|
||||
archive_set_error (a, 0, "%s: %s", G_STRFUNC, error->message);
|
||||
g_clear_error (&error);
|
||||
|
||||
return ARCHIVE_FATAL;
|
||||
}
|
||||
|
||||
*buffer = data->buffer;
|
||||
|
||||
return read_count;
|
||||
}
|
||||
|
||||
static int
|
||||
file_gex_close_callback (struct archive *a,
|
||||
void *client_data)
|
||||
{
|
||||
/* Input allocated outside, let's also unref it outside. */
|
||||
GexReadData *data = client_data;
|
||||
|
||||
g_free (data->buffer);
|
||||
|
||||
return ARCHIVE_OK;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
file_gex_validate_path (const gchar *path,
|
||||
const gchar *file_name,
|
||||
gboolean first,
|
||||
gchar **plugin_id,
|
||||
GError **error)
|
||||
{
|
||||
gchar *dirname = g_path_get_dirname (path);
|
||||
gboolean valid = TRUE;
|
||||
|
||||
if (g_path_is_absolute (path) || g_strcmp0 (dirname, "/") == 0)
|
||||
{
|
||||
*error = g_error_new (PIKA_EXTENSION_ERROR, PIKA_EXTENSION_FAILED,
|
||||
_("Absolute path are forbidden in PIKA extension '%s': %s"),
|
||||
file_name, path);
|
||||
g_free (dirname);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (g_strcmp0 (dirname, ".") == 0)
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
*error = g_error_new (PIKA_EXTENSION_ERROR, PIKA_EXTENSION_FAILED,
|
||||
_("File not allowed in root of PIKA extension '%s': %s"),
|
||||
file_name, path);
|
||||
valid = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*plugin_id)
|
||||
{
|
||||
if (g_strcmp0 (path, *plugin_id) != 0)
|
||||
{
|
||||
*error = g_error_new (PIKA_EXTENSION_ERROR, PIKA_EXTENSION_FAILED,
|
||||
_("File not in PIKA extension '%s' folder id '%s': %s"),
|
||||
file_name, *plugin_id, path);
|
||||
valid = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*plugin_id = g_strdup (path);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
valid = file_gex_validate_path (dirname, file_name, FALSE, plugin_id, error);
|
||||
}
|
||||
|
||||
g_free (dirname);
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* file_gex_validate:
|
||||
* @file:
|
||||
* @appstream:
|
||||
* @error:
|
||||
*
|
||||
* Validate the extension file with the following tests:
|
||||
* - No absolute path allowed.
|
||||
* - All files must be in a single folder which determines the extension
|
||||
* ID.
|
||||
* - This folder must contain the AppStream metadata file which must be
|
||||
* valid AppStream XML format.
|
||||
* - The extension ID resulting from the AppStream parsing must
|
||||
* correspond to the extension ID resulting from the top folder.
|
||||
*
|
||||
* Returns: TRUE on success and allocates @appstream, FALSE otherwise
|
||||
* with @error set.
|
||||
*/
|
||||
static gboolean
|
||||
file_gex_validate (GFile *file,
|
||||
AsApp **appstream,
|
||||
GError **error)
|
||||
{
|
||||
GInputStream *input;
|
||||
gboolean success = FALSE;
|
||||
|
||||
g_return_val_if_fail (error != NULL && *error == NULL, FALSE);
|
||||
g_return_val_if_fail (appstream != NULL && *appstream == NULL, FALSE);
|
||||
|
||||
input = G_INPUT_STREAM (g_file_read (file, NULL, error));
|
||||
|
||||
if (input)
|
||||
{
|
||||
struct archive *a;
|
||||
struct archive_entry *entry;
|
||||
int r;
|
||||
GexReadData user_data;
|
||||
|
||||
user_data.input = input;
|
||||
if ((a = archive_read_new ()))
|
||||
{
|
||||
archive_read_support_format_zip (a);
|
||||
|
||||
r = archive_read_open (a, &user_data, file_gex_open_callback,
|
||||
file_gex_read_callback, file_gex_close_callback);
|
||||
if (r == ARCHIVE_OK)
|
||||
{
|
||||
gchar *appdata_path = NULL;
|
||||
GBytes *appdata = NULL;
|
||||
gchar *plugin_id = NULL;
|
||||
|
||||
while (archive_read_next_header (a, &entry) == ARCHIVE_OK &&
|
||||
file_gex_validate_path (archive_entry_pathname (entry),
|
||||
pika_file_get_utf8_name (file),
|
||||
TRUE, &plugin_id, error))
|
||||
{
|
||||
if (plugin_id && ! appdata_path)
|
||||
appdata_path = g_strdup_printf ("%s/%s.metainfo.xml", plugin_id, plugin_id);
|
||||
|
||||
if (appdata_path)
|
||||
{
|
||||
if (g_strcmp0 (appdata_path, archive_entry_pathname (entry)) == 0)
|
||||
{
|
||||
const void *buffer;
|
||||
GString *appstring = g_string_new ("");
|
||||
la_int64_t offset;
|
||||
size_t size;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
r = archive_read_data_block (a, &buffer, &size, &offset);
|
||||
|
||||
if (r == ARCHIVE_FATAL)
|
||||
{
|
||||
*error = g_error_new (PIKA_EXTENSION_ERROR, PIKA_EXTENSION_FAILED,
|
||||
_("Fatal error when uncompressing PIKA extension '%s': %s"),
|
||||
pika_file_get_utf8_name (file),
|
||||
archive_error_string (a));
|
||||
g_string_free (appstring, TRUE);
|
||||
break;
|
||||
}
|
||||
else if (r == ARCHIVE_EOF)
|
||||
{
|
||||
appdata = g_string_free_to_bytes (appstring);
|
||||
break;
|
||||
}
|
||||
|
||||
appstring = g_string_append_len (appstring, (const gchar *) buffer, size);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
archive_read_data_skip (a);
|
||||
}
|
||||
|
||||
if (! (*error))
|
||||
{
|
||||
if (appdata)
|
||||
{
|
||||
*appstream = as_app_new ();
|
||||
|
||||
if (! as_app_parse_data (*appstream, appdata,
|
||||
AS_APP_PARSE_FLAG_USE_HEURISTICS,
|
||||
error))
|
||||
{
|
||||
g_clear_object (appstream);
|
||||
}
|
||||
else if (g_strcmp0 (as_app_get_id (*appstream), plugin_id) != 0)
|
||||
{
|
||||
*error = g_error_new (PIKA_EXTENSION_ERROR, PIKA_EXTENSION_FAILED,
|
||||
_("PIKA extension '%s' directory (%s) different from AppStream id: %s"),
|
||||
pika_file_get_utf8_name (file),
|
||||
plugin_id, as_app_get_id (*appstream));
|
||||
g_clear_object (appstream);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*error = g_error_new (PIKA_EXTENSION_ERROR, PIKA_EXTENSION_FAILED,
|
||||
_("PIKA extension '%s' requires an AppStream file: %s"),
|
||||
pika_file_get_utf8_name (file),
|
||||
appdata_path);
|
||||
}
|
||||
}
|
||||
if (appdata_path)
|
||||
g_free (appdata_path);
|
||||
if (appdata)
|
||||
g_bytes_unref (appdata);
|
||||
if (plugin_id)
|
||||
g_free (plugin_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
*error = g_error_new (PIKA_EXTENSION_ERROR, PIKA_EXTENSION_FAILED,
|
||||
_("Invalid PIKA extension '%s': %s"),
|
||||
pika_file_get_utf8_name (file),
|
||||
archive_error_string (a));
|
||||
}
|
||||
|
||||
archive_read_close (a);
|
||||
archive_read_free (a);
|
||||
if (! *error)
|
||||
success = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
*error = g_error_new (PIKA_EXTENSION_ERROR, PIKA_EXTENSION_FAILED,
|
||||
"%s: archive_read_new() failed.", G_STRFUNC);
|
||||
}
|
||||
|
||||
g_object_unref (input);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_prefix_error (error, _("Could not open '%s' for reading: "),
|
||||
pika_file_get_utf8_name (file));
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
file_gex_decompress (GFile *file,
|
||||
gchar *plugin_id,
|
||||
GError **error)
|
||||
{
|
||||
GInputStream *input;
|
||||
GFile *ext_dir = pika_directory_file ("extensions", NULL);
|
||||
gchar *plugin_dir = NULL;
|
||||
gboolean success = FALSE;
|
||||
|
||||
g_return_val_if_fail (error != NULL && *error == NULL, FALSE);
|
||||
g_return_val_if_fail (plugin_id != NULL, FALSE);
|
||||
|
||||
input = G_INPUT_STREAM (g_file_read (file, NULL, error));
|
||||
|
||||
if (input)
|
||||
{
|
||||
struct archive *a;
|
||||
struct archive *ext;
|
||||
struct archive_entry *entry;
|
||||
int r;
|
||||
GexReadData user_data;
|
||||
const void *buffer;
|
||||
|
||||
user_data.input = input;
|
||||
if ((a = archive_read_new ()))
|
||||
{
|
||||
archive_read_support_format_zip (a);
|
||||
|
||||
ext = archive_write_disk_new ();
|
||||
archive_write_disk_set_options (ext,
|
||||
ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM |
|
||||
ARCHIVE_EXTRACT_ACL | ARCHIVE_EXTRACT_FFLAGS |
|
||||
ARCHIVE_EXTRACT_SECURE_NODOTDOT |
|
||||
ARCHIVE_EXTRACT_SECURE_SYMLINKS | ARCHIVE_EXTRACT_NO_OVERWRITE);
|
||||
archive_write_disk_set_standard_lookup (ext);
|
||||
|
||||
r = archive_read_open (a, &user_data, file_gex_open_callback,
|
||||
file_gex_read_callback, file_gex_close_callback);
|
||||
if (r == ARCHIVE_OK)
|
||||
{
|
||||
while (archive_read_next_header (a, &entry) == ARCHIVE_OK &&
|
||||
/* Re-validate just in case the archive got swapped
|
||||
* between validation and decompression. */
|
||||
file_gex_validate_path (archive_entry_pathname (entry),
|
||||
pika_file_get_utf8_name (file),
|
||||
TRUE, &plugin_id, error))
|
||||
{
|
||||
gchar *path;
|
||||
size_t size;
|
||||
la_int64_t offset;
|
||||
|
||||
path = g_build_filename (g_file_get_path (ext_dir), archive_entry_pathname (entry), NULL);
|
||||
|
||||
archive_entry_set_pathname (entry, path);
|
||||
g_free (path);
|
||||
|
||||
r = archive_write_header (ext, entry);
|
||||
if (r < ARCHIVE_WARN)
|
||||
{
|
||||
*error = g_error_new (PIKA_EXTENSION_ERROR, PIKA_EXTENSION_FAILED,
|
||||
_("Fatal error when uncompressing PIKA extension '%s': %s"),
|
||||
pika_file_get_utf8_name (file),
|
||||
archive_error_string (ext));
|
||||
break;
|
||||
}
|
||||
|
||||
if (archive_entry_size (entry) > 0)
|
||||
{
|
||||
while (TRUE)
|
||||
{
|
||||
r = archive_read_data_block (a, &buffer, &size, &offset);
|
||||
if (r == ARCHIVE_EOF)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (r < ARCHIVE_WARN)
|
||||
{
|
||||
*error = g_error_new (PIKA_EXTENSION_ERROR, PIKA_EXTENSION_FAILED,
|
||||
_("Fatal error when uncompressing PIKA extension '%s': %s"),
|
||||
pika_file_get_utf8_name (file),
|
||||
archive_error_string (a));
|
||||
break;
|
||||
}
|
||||
|
||||
r = archive_write_data_block (ext, buffer, size, offset);
|
||||
if (r == ARCHIVE_WARN)
|
||||
{
|
||||
g_printerr (_("Warning when uncompressing PIKA extension '%s': %s\n"),
|
||||
pika_file_get_utf8_name (file),
|
||||
archive_error_string (ext));
|
||||
break;
|
||||
}
|
||||
else if (r < ARCHIVE_OK)
|
||||
{
|
||||
*error = g_error_new (PIKA_EXTENSION_ERROR, PIKA_EXTENSION_FAILED,
|
||||
_("Fatal error when uncompressing PIKA extension '%s': %s"),
|
||||
pika_file_get_utf8_name (file),
|
||||
archive_error_string (ext));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (*error)
|
||||
break;
|
||||
|
||||
r = archive_write_finish_entry (ext);
|
||||
if (r < ARCHIVE_OK)
|
||||
{
|
||||
*error = g_error_new (PIKA_EXTENSION_ERROR, PIKA_EXTENSION_FAILED,
|
||||
_("Fatal error when uncompressing PIKA extension '%s': %s"),
|
||||
pika_file_get_utf8_name (file),
|
||||
archive_error_string (ext));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*error = g_error_new (PIKA_EXTENSION_ERROR, PIKA_EXTENSION_FAILED,
|
||||
_("Invalid PIKA extension '%s': %s"),
|
||||
pika_file_get_utf8_name (file),
|
||||
archive_error_string (a));
|
||||
}
|
||||
|
||||
archive_read_close (a);
|
||||
archive_read_free (a);
|
||||
archive_write_close(ext);
|
||||
archive_write_free(ext);
|
||||
|
||||
if (! *error)
|
||||
success = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
*error = g_error_new (PIKA_EXTENSION_ERROR, PIKA_EXTENSION_FAILED,
|
||||
"%s: archive_read_new() failed.", G_STRFUNC);
|
||||
}
|
||||
|
||||
g_object_unref (input);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_prefix_error (error, _("Could not open '%s' for reading: "),
|
||||
pika_file_get_utf8_name (file));
|
||||
}
|
||||
|
||||
if (success)
|
||||
plugin_dir = g_build_filename (g_file_get_path (ext_dir), plugin_id, NULL);
|
||||
|
||||
g_object_unref (ext_dir);
|
||||
|
||||
return plugin_dir;
|
||||
}
|
||||
|
||||
/* public functions */
|
||||
|
||||
PikaValueArray *
|
||||
file_gex_load_invoker (PikaProcedure *procedure,
|
||||
Pika *pika,
|
||||
PikaContext *context,
|
||||
PikaProgress *progress,
|
||||
const PikaValueArray *args,
|
||||
GError **error)
|
||||
{
|
||||
PikaValueArray *return_vals;
|
||||
GFile *file;
|
||||
gchar *ext_dir = NULL;
|
||||
AsApp *appdata = NULL;
|
||||
gboolean success = FALSE;
|
||||
|
||||
pika_set_busy (pika);
|
||||
|
||||
file = g_value_get_object (pika_value_array_index (args, 1));
|
||||
|
||||
success = file_gex_validate (file, &appdata, error);
|
||||
if (success)
|
||||
ext_dir = file_gex_decompress (file, (gchar *) as_app_get_id (appdata),
|
||||
error);
|
||||
|
||||
if (ext_dir)
|
||||
{
|
||||
PikaExtension *extension;
|
||||
GError *rm_error = NULL;
|
||||
|
||||
extension = pika_extension_new (ext_dir, TRUE);
|
||||
success = pika_extension_manager_install (pika->extension_manager,
|
||||
extension, error);
|
||||
|
||||
if (! success)
|
||||
{
|
||||
GFile *file;
|
||||
|
||||
g_object_unref (extension);
|
||||
|
||||
file = g_file_new_for_path (ext_dir);
|
||||
|
||||
if (! pika_file_delete_recursive (file, &rm_error))
|
||||
{
|
||||
g_warning ("%s: %s\n", G_STRFUNC, rm_error->message);
|
||||
g_error_free (rm_error);
|
||||
}
|
||||
|
||||
g_object_unref (file);
|
||||
}
|
||||
|
||||
g_free (ext_dir);
|
||||
}
|
||||
else
|
||||
{
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
return_vals = pika_procedure_get_return_values (procedure, success,
|
||||
error ? *error : NULL);
|
||||
pika_unset_busy (pika);
|
||||
|
||||
return return_vals;
|
||||
}
|
36
app/file-data/file-data-gex.h
Normal file
36
app/file-data/file-data-gex.h
Normal file
@ -0,0 +1,36 @@
|
||||
/* PIKA - Photo and Image Kooker Application
|
||||
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
|
||||
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
|
||||
*
|
||||
* Original copyright, applying to most contents (license remains unchanged):
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
* Copyright (C) 2019 Jehan
|
||||
*
|
||||
* 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 __FILE_DATA_GEX_H__
|
||||
#define __FILE_DATA_GEX_H__
|
||||
|
||||
|
||||
PikaValueArray * file_gex_load_invoker (PikaProcedure *procedure,
|
||||
Pika *pika,
|
||||
PikaContext *context,
|
||||
PikaProgress *progress,
|
||||
const PikaValueArray *args,
|
||||
GError **error);
|
||||
|
||||
|
||||
#endif /* __FILE_DATA_GEX_H__ */
|
||||
|
365
app/file-data/file-data-gih.c
Normal file
365
app/file-data/file-data-gih.c
Normal file
@ -0,0 +1,365 @@
|
||||
/* PIKA - Photo and Image Kooker Application
|
||||
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
|
||||
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
|
||||
*
|
||||
* Original copyright, applying to most contents (license remains unchanged):
|
||||
* 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 <cairo.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include <gegl.h>
|
||||
|
||||
#include "libpikabase/pikabase.h"
|
||||
#include "libpikabase/pikaparasiteio.h"
|
||||
#include "libpikacolor/pikacolor.h"
|
||||
|
||||
#include "core/core-types.h"
|
||||
|
||||
#include "core/pika.h"
|
||||
#include "core/pikabrushpipe.h"
|
||||
#include "core/pikabrushpipe-load.h"
|
||||
#include "core/pikabrush-private.h"
|
||||
#include "core/pikadrawable.h"
|
||||
#include "core/pikaimage.h"
|
||||
#include "core/pikalayer-new.h"
|
||||
#include "core/pikaparamspecs.h"
|
||||
#include "core/pikatempbuf.h"
|
||||
|
||||
#include "pdb/pikaprocedure.h"
|
||||
|
||||
#include "file-data-gbr.h"
|
||||
#include "file-data-gih.h"
|
||||
|
||||
#include "pika-intl.h"
|
||||
|
||||
|
||||
/* local function prototypes */
|
||||
|
||||
static PikaImage * file_gih_pipe_to_image (Pika *pika,
|
||||
PikaBrushPipe *pipe);
|
||||
static PikaBrushPipe * file_gih_image_to_pipe (PikaImage *image,
|
||||
const gchar *name,
|
||||
gdouble spacing,
|
||||
const gchar *paramstring);
|
||||
|
||||
|
||||
/* public functions */
|
||||
|
||||
PikaValueArray *
|
||||
file_gih_load_invoker (PikaProcedure *procedure,
|
||||
Pika *pika,
|
||||
PikaContext *context,
|
||||
PikaProgress *progress,
|
||||
const PikaValueArray *args,
|
||||
GError **error)
|
||||
{
|
||||
PikaValueArray *return_vals;
|
||||
PikaImage *image = NULL;
|
||||
GFile *file;
|
||||
GInputStream *input;
|
||||
GError *my_error = NULL;
|
||||
|
||||
pika_set_busy (pika);
|
||||
|
||||
file = g_value_get_object (pika_value_array_index (args, 1));
|
||||
|
||||
input = G_INPUT_STREAM (g_file_read (file, NULL, &my_error));
|
||||
|
||||
if (input)
|
||||
{
|
||||
GList *list = pika_brush_pipe_load (context, file, input, error);
|
||||
|
||||
if (list)
|
||||
{
|
||||
PikaBrushPipe *pipe = list->data;
|
||||
|
||||
g_list_free (list);
|
||||
|
||||
image = file_gih_pipe_to_image (pika, pipe);
|
||||
g_object_unref (pipe);
|
||||
}
|
||||
|
||||
g_object_unref (input);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_propagate_prefixed_error (error, my_error,
|
||||
_("Could not open '%s' for reading: "),
|
||||
pika_file_get_utf8_name (file));
|
||||
}
|
||||
|
||||
return_vals = pika_procedure_get_return_values (procedure, image != NULL,
|
||||
error ? *error : NULL);
|
||||
|
||||
if (image)
|
||||
g_value_set_object (pika_value_array_index (return_vals, 1), image);
|
||||
|
||||
pika_unset_busy (pika);
|
||||
|
||||
return return_vals;
|
||||
}
|
||||
|
||||
PikaValueArray *
|
||||
file_gih_save_invoker (PikaProcedure *procedure,
|
||||
Pika *pika,
|
||||
PikaContext *context,
|
||||
PikaProgress *progress,
|
||||
const PikaValueArray *args,
|
||||
GError **error)
|
||||
{
|
||||
PikaValueArray *return_vals;
|
||||
PikaImage *image;
|
||||
PikaBrushPipe *pipe;
|
||||
const gchar *name;
|
||||
const gchar *params;
|
||||
GFile *file;
|
||||
gint spacing;
|
||||
gboolean success;
|
||||
|
||||
pika_set_busy (pika);
|
||||
|
||||
image = g_value_get_object (pika_value_array_index (args, 1));
|
||||
/* XXX: drawable list is currently unused. GIH saving just uses the
|
||||
* whole layer list.
|
||||
*/
|
||||
file = g_value_get_object (pika_value_array_index (args, 4));
|
||||
spacing = g_value_get_int (pika_value_array_index (args, 5));
|
||||
name = g_value_get_string (pika_value_array_index (args, 6));
|
||||
params = g_value_get_string (pika_value_array_index (args, 7));
|
||||
|
||||
pipe = file_gih_image_to_pipe (image, name, spacing, params);
|
||||
|
||||
pika_data_set_file (PIKA_DATA (pipe), file, TRUE, TRUE);
|
||||
|
||||
success = pika_data_save (PIKA_DATA (pipe), error);
|
||||
|
||||
g_object_unref (pipe);
|
||||
|
||||
return_vals = pika_procedure_get_return_values (procedure, success,
|
||||
error ? *error : NULL);
|
||||
|
||||
pika_unset_busy (pika);
|
||||
|
||||
return return_vals;
|
||||
}
|
||||
|
||||
|
||||
/* private functions */
|
||||
|
||||
static PikaImage *
|
||||
file_gih_pipe_to_image (Pika *pika,
|
||||
PikaBrushPipe *pipe)
|
||||
{
|
||||
PikaImage *image;
|
||||
const gchar *name;
|
||||
PikaImageBaseType base_type;
|
||||
PikaParasite *parasite;
|
||||
gchar spacing[8];
|
||||
gint i;
|
||||
|
||||
if (pika_brush_get_pixmap (pipe->current))
|
||||
base_type = PIKA_RGB;
|
||||
else
|
||||
base_type = PIKA_GRAY;
|
||||
|
||||
name = pika_object_get_name (pipe);
|
||||
|
||||
image = pika_image_new (pika, 1, 1, base_type,
|
||||
PIKA_PRECISION_U8_NON_LINEAR);
|
||||
|
||||
parasite = pika_parasite_new ("pika-brush-pipe-name",
|
||||
PIKA_PARASITE_PERSISTENT,
|
||||
strlen (name) + 1, name);
|
||||
pika_image_parasite_attach (image, parasite, FALSE);
|
||||
pika_parasite_free (parasite);
|
||||
|
||||
g_snprintf (spacing, sizeof (spacing), "%d",
|
||||
pika_brush_get_spacing (PIKA_BRUSH (pipe)));
|
||||
|
||||
parasite = pika_parasite_new ("pika-brush-pipe-spacing",
|
||||
PIKA_PARASITE_PERSISTENT,
|
||||
strlen (spacing) + 1, spacing);
|
||||
pika_image_parasite_attach (image, parasite, FALSE);
|
||||
pika_parasite_free (parasite);
|
||||
|
||||
for (i = 0; i < pipe->n_brushes; i++)
|
||||
{
|
||||
PikaLayer *layer;
|
||||
|
||||
layer = file_gbr_brush_to_layer (image, pipe->brushes[i]);
|
||||
pika_image_add_layer (image, layer, NULL, i, FALSE);
|
||||
}
|
||||
|
||||
if (pipe->params)
|
||||
{
|
||||
PikaPixPipeParams params;
|
||||
gchar *paramstring;
|
||||
|
||||
/* Since we do not (yet) load the pipe as described in the
|
||||
* header, but use one layer per brush, we have to alter the
|
||||
* paramstring before attaching it as a parasite.
|
||||
*
|
||||
* (this comment copied over from file-gih, whatever "as
|
||||
* described in the header" means) -- mitch
|
||||
*/
|
||||
|
||||
pika_pixpipe_params_init (¶ms);
|
||||
pika_pixpipe_params_parse (pipe->params, ¶ms);
|
||||
|
||||
params.cellwidth = pika_image_get_width (image);
|
||||
params.cellheight = pika_image_get_height (image);
|
||||
params.cols = 1;
|
||||
params.rows = 1;
|
||||
|
||||
paramstring = pika_pixpipe_params_build (¶ms);
|
||||
if (paramstring)
|
||||
{
|
||||
parasite = pika_parasite_new ("pika-brush-pipe-parameters",
|
||||
PIKA_PARASITE_PERSISTENT,
|
||||
strlen (paramstring) + 1,
|
||||
paramstring);
|
||||
pika_image_parasite_attach (image, parasite, FALSE);
|
||||
pika_parasite_free (parasite);
|
||||
g_free (paramstring);
|
||||
}
|
||||
|
||||
pika_pixpipe_params_free (¶ms);
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
static PikaBrushPipe *
|
||||
file_gih_image_to_pipe (PikaImage *image,
|
||||
const gchar *name,
|
||||
gdouble spacing,
|
||||
const gchar *paramstring)
|
||||
{
|
||||
PikaBrushPipe *pipe;
|
||||
PikaPixPipeParams params;
|
||||
GList *layers;
|
||||
GList *list;
|
||||
GList *brushes = NULL;
|
||||
gint image_width;
|
||||
gint image_height;
|
||||
gint i;
|
||||
|
||||
pipe = g_object_new (PIKA_TYPE_BRUSH_PIPE,
|
||||
"name", name,
|
||||
"mime-type", "image/x-pika-gih",
|
||||
"spacing", spacing,
|
||||
NULL);
|
||||
|
||||
pika_pixpipe_params_init (¶ms);
|
||||
pika_pixpipe_params_parse (paramstring, ¶ms);
|
||||
|
||||
image_width = pika_image_get_width (image);
|
||||
image_height = pika_image_get_height (image);
|
||||
|
||||
layers = pika_image_get_layer_iter (image);
|
||||
|
||||
for (list = layers; list; list = g_list_next (list))
|
||||
{
|
||||
PikaLayer *layer = list->data;
|
||||
gint width;
|
||||
gint height;
|
||||
gint offset_x;
|
||||
gint offset_y;
|
||||
gint row;
|
||||
|
||||
width = pika_item_get_width (PIKA_ITEM (layer));
|
||||
height = pika_item_get_height (PIKA_ITEM (layer));
|
||||
|
||||
pika_item_get_offset (PIKA_ITEM (layer), &offset_x, &offset_y);
|
||||
|
||||
/* Since we assume positive layer offsets we need to make sure this
|
||||
* is always the case or we will crash for grayscale layers.
|
||||
* See issue #6436. */
|
||||
if (offset_x < 0)
|
||||
{
|
||||
g_warning (_("Negative x offset: %d for layer %s corrected."),
|
||||
offset_x, pika_object_get_name (layer));
|
||||
width += offset_x;
|
||||
offset_x = 0;
|
||||
}
|
||||
if (offset_y < 0)
|
||||
{
|
||||
g_warning (_("Negative y offset: %d for layer %s corrected."),
|
||||
offset_y, pika_object_get_name (layer));
|
||||
height += offset_y;
|
||||
offset_y = 0;
|
||||
}
|
||||
|
||||
for (row = 0; row < params.rows; row++)
|
||||
{
|
||||
gint y, ynext;
|
||||
gint thisy, thish;
|
||||
gint col;
|
||||
|
||||
y = (row * image_height) / params.rows;
|
||||
ynext = ((row + 1) * image_height / params.rows);
|
||||
|
||||
/* Assume layer is offset to positive direction in x and y.
|
||||
* That's reasonable, as otherwise all of the layer
|
||||
* won't be visible.
|
||||
* thisy and thisx are in the drawable's coordinate space.
|
||||
*/
|
||||
thisy = MAX (0, y - offset_y);
|
||||
thish = (ynext - offset_y) - thisy;
|
||||
thish = MIN (thish, height - thisy);
|
||||
|
||||
for (col = 0; col < params.cols; col++)
|
||||
{
|
||||
PikaBrush *brush;
|
||||
gint x, xnext;
|
||||
gint thisx, thisw;
|
||||
|
||||
x = (col * image_width / params.cols);
|
||||
xnext = ((col + 1) * image_width / params.cols);
|
||||
thisx = MAX (0, x - offset_x);
|
||||
thisw = (xnext - offset_x) - thisx;
|
||||
thisw = MIN (thisw, width - thisx);
|
||||
|
||||
brush = file_gbr_drawable_to_brush (PIKA_DRAWABLE (layer),
|
||||
GEGL_RECTANGLE (thisx, thisy,
|
||||
thisw, thish),
|
||||
pika_object_get_name (layer),
|
||||
spacing);
|
||||
|
||||
brushes = g_list_prepend (brushes, brush);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
brushes = g_list_reverse (brushes);
|
||||
|
||||
pipe->n_brushes = g_list_length (brushes);
|
||||
pipe->brushes = g_new0 (PikaBrush *, pipe->n_brushes);
|
||||
|
||||
for (list = brushes, i = 0; list; list = g_list_next (list), i++)
|
||||
pipe->brushes[i] = list->data;
|
||||
|
||||
g_list_free (brushes);
|
||||
|
||||
pika_pixpipe_params_free (¶ms);
|
||||
|
||||
pika_brush_pipe_set_params (pipe, paramstring);
|
||||
|
||||
return pipe;
|
||||
}
|
41
app/file-data/file-data-gih.h
Normal file
41
app/file-data/file-data-gih.h
Normal file
@ -0,0 +1,41 @@
|
||||
/* PIKA - Photo and Image Kooker Application
|
||||
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
|
||||
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
|
||||
*
|
||||
* Original copyright, applying to most contents (license remains unchanged):
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef __FILE_DATA_GIH_H__
|
||||
#define __FILE_DATA_GIH_H__
|
||||
|
||||
|
||||
PikaValueArray * file_gih_load_invoker (PikaProcedure *procedure,
|
||||
Pika *pika,
|
||||
PikaContext *context,
|
||||
PikaProgress *progress,
|
||||
const PikaValueArray *args,
|
||||
GError **error);
|
||||
|
||||
PikaValueArray * file_gih_save_invoker (PikaProcedure *procedure,
|
||||
Pika *pika,
|
||||
PikaContext *context,
|
||||
PikaProgress *progress,
|
||||
const PikaValueArray *args,
|
||||
GError **error);
|
||||
|
||||
|
||||
#endif /* __FILE_DATA_GIH_H__ */
|
310
app/file-data/file-data-pat.c
Normal file
310
app/file-data/file-data-pat.c
Normal file
@ -0,0 +1,310 @@
|
||||
/* PIKA - Photo and Image Kooker Application
|
||||
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
|
||||
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
|
||||
*
|
||||
* Original copyright, applying to most contents (license remains unchanged):
|
||||
* 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 <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include <gegl.h>
|
||||
|
||||
#include "libpikabase/pikabase.h"
|
||||
#include "libpikaconfig/pikaconfig.h"
|
||||
|
||||
#include "core/core-types.h"
|
||||
|
||||
#include "gegl/pika-babl.h"
|
||||
|
||||
#include "core/pika.h"
|
||||
#include "core/pikacontainer.h"
|
||||
#include "core/pikadrawable.h"
|
||||
#include "core/pikaimage.h"
|
||||
#include "core/pikaimage-new.h"
|
||||
#include "core/pikaimage-resize.h"
|
||||
#include "core/pikalayer-new.h"
|
||||
#include "core/pikaparamspecs.h"
|
||||
#include "core/pikapattern.h"
|
||||
#include "core/pikapattern-load.h"
|
||||
#include "core/pikapickable.h"
|
||||
#include "core/pikatempbuf.h"
|
||||
|
||||
#include "pdb/pikaprocedure.h"
|
||||
|
||||
#include "file-data-pat.h"
|
||||
|
||||
#include "pika-intl.h"
|
||||
|
||||
|
||||
/* local function prototypes */
|
||||
|
||||
static PikaImage * file_pat_pattern_to_image (Pika *pika,
|
||||
PikaPattern *pattern);
|
||||
static PikaPattern * file_pat_image_to_pattern (PikaImage *image,
|
||||
PikaContext *context,
|
||||
gint n_drawables,
|
||||
PikaDrawable **drawables,
|
||||
const gchar *name);
|
||||
|
||||
|
||||
/* public functions */
|
||||
|
||||
PikaValueArray *
|
||||
file_pat_load_invoker (PikaProcedure *procedure,
|
||||
Pika *pika,
|
||||
PikaContext *context,
|
||||
PikaProgress *progress,
|
||||
const PikaValueArray *args,
|
||||
GError **error)
|
||||
{
|
||||
PikaValueArray *return_vals;
|
||||
PikaImage *image = NULL;
|
||||
GFile *file;
|
||||
GInputStream *input;
|
||||
GError *my_error = NULL;
|
||||
|
||||
pika_set_busy (pika);
|
||||
|
||||
file = g_value_get_object (pika_value_array_index (args, 1));
|
||||
|
||||
input = G_INPUT_STREAM (g_file_read (file, NULL, &my_error));
|
||||
|
||||
if (input)
|
||||
{
|
||||
GList *list = pika_pattern_load (context, file, input, error);
|
||||
|
||||
if (list)
|
||||
{
|
||||
PikaPattern *pattern = list->data;
|
||||
|
||||
g_list_free (list);
|
||||
|
||||
image = file_pat_pattern_to_image (pika, pattern);
|
||||
g_object_unref (pattern);
|
||||
}
|
||||
|
||||
g_object_unref (input);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_propagate_prefixed_error (error, my_error,
|
||||
_("Could not open '%s' for reading: "),
|
||||
pika_file_get_utf8_name (file));
|
||||
}
|
||||
|
||||
return_vals = pika_procedure_get_return_values (procedure, image != NULL,
|
||||
error ? *error : NULL);
|
||||
|
||||
if (image)
|
||||
g_value_set_object (pika_value_array_index (return_vals, 1), image);
|
||||
|
||||
pika_unset_busy (pika);
|
||||
|
||||
return return_vals;
|
||||
}
|
||||
|
||||
PikaValueArray *
|
||||
file_pat_save_invoker (PikaProcedure *procedure,
|
||||
Pika *pika,
|
||||
PikaContext *context,
|
||||
PikaProgress *progress,
|
||||
const PikaValueArray *args,
|
||||
GError **error)
|
||||
{
|
||||
PikaValueArray *return_vals;
|
||||
PikaImage *image;
|
||||
PikaPattern *pattern;
|
||||
const gchar *name;
|
||||
GFile *file;
|
||||
PikaDrawable **drawables;
|
||||
gint n_drawables;
|
||||
gboolean success;
|
||||
|
||||
pika_set_busy (pika);
|
||||
|
||||
image = g_value_get_object (pika_value_array_index (args, 1));
|
||||
n_drawables = g_value_get_int (pika_value_array_index (args, 2));
|
||||
drawables = (PikaDrawable **) pika_value_get_object_array (pika_value_array_index (args, 3));
|
||||
file = g_value_get_object (pika_value_array_index (args, 4));
|
||||
name = g_value_get_string (pika_value_array_index (args, 5));
|
||||
|
||||
pattern = file_pat_image_to_pattern (image, context, n_drawables, drawables, name);
|
||||
|
||||
pika_data_set_file (PIKA_DATA (pattern), file, TRUE, TRUE);
|
||||
|
||||
success = pika_data_save (PIKA_DATA (pattern), error);
|
||||
|
||||
g_object_unref (pattern);
|
||||
|
||||
return_vals = pika_procedure_get_return_values (procedure, success,
|
||||
error ? *error : NULL);
|
||||
|
||||
pika_unset_busy (pika);
|
||||
|
||||
return return_vals;
|
||||
}
|
||||
|
||||
|
||||
/* private functions */
|
||||
|
||||
static PikaImage *
|
||||
file_pat_pattern_to_image (Pika *pika,
|
||||
PikaPattern *pattern)
|
||||
{
|
||||
PikaImage *image;
|
||||
PikaLayer *layer;
|
||||
const Babl *format;
|
||||
PikaImageBaseType base_type;
|
||||
gboolean alpha;
|
||||
gint width;
|
||||
gint height;
|
||||
PikaTempBuf *mask = pika_pattern_get_mask (pattern);
|
||||
GeglBuffer *buffer;
|
||||
GString *string;
|
||||
PikaConfigWriter *writer;
|
||||
PikaParasite *parasite;
|
||||
|
||||
format = pika_temp_buf_get_format (mask);
|
||||
|
||||
switch (babl_format_get_bytes_per_pixel (format))
|
||||
{
|
||||
case 1:
|
||||
base_type = PIKA_GRAY;
|
||||
alpha = FALSE;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
base_type = PIKA_GRAY;
|
||||
alpha = TRUE;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
base_type = PIKA_RGB;
|
||||
alpha = FALSE;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
base_type = PIKA_RGB;
|
||||
alpha = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
g_return_val_if_reached (NULL);
|
||||
}
|
||||
|
||||
width = pika_temp_buf_get_width (mask);
|
||||
height = pika_temp_buf_get_height (mask);
|
||||
|
||||
image = pika_image_new (pika, width, height, base_type,
|
||||
PIKA_PRECISION_U8_NON_LINEAR);
|
||||
|
||||
string = g_string_new (NULL);
|
||||
writer = pika_config_writer_new_from_string (string);
|
||||
|
||||
pika_config_writer_open (writer, "description");
|
||||
pika_config_writer_string (writer, pika_object_get_name (pattern));
|
||||
pika_config_writer_close (writer);
|
||||
|
||||
pika_config_writer_finish (writer, NULL, NULL);
|
||||
|
||||
parasite = pika_parasite_new ("PikaProcedureConfig-file-pat-save-last",
|
||||
PIKA_PARASITE_PERSISTENT,
|
||||
string->len + 1, string->str);
|
||||
pika_image_parasite_attach (image, parasite, FALSE);
|
||||
pika_parasite_free (parasite);
|
||||
|
||||
g_string_free (string, TRUE);
|
||||
|
||||
format = pika_image_get_layer_format (image, alpha);
|
||||
|
||||
layer = pika_layer_new (image, width, height, format,
|
||||
pika_object_get_name (pattern),
|
||||
1.0, PIKA_LAYER_MODE_NORMAL);
|
||||
pika_image_add_layer (image, layer, NULL, 0, FALSE);
|
||||
|
||||
buffer = pika_drawable_get_buffer (PIKA_DRAWABLE (layer));
|
||||
|
||||
gegl_buffer_set (buffer, GEGL_RECTANGLE (0, 0, width, height), 0,
|
||||
NULL,
|
||||
pika_temp_buf_get_data (mask), GEGL_AUTO_ROWSTRIDE);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
static PikaPattern *
|
||||
file_pat_image_to_pattern (PikaImage *image,
|
||||
PikaContext *context,
|
||||
gint n_drawables,
|
||||
PikaDrawable **drawables,
|
||||
const gchar *name)
|
||||
{
|
||||
PikaPattern *pattern;
|
||||
PikaImage *subimage = NULL;
|
||||
const Babl *format;
|
||||
gint width;
|
||||
gint height;
|
||||
|
||||
g_return_val_if_fail (n_drawables > 0, NULL);
|
||||
|
||||
if (n_drawables > 1)
|
||||
{
|
||||
GList *drawable_list = NULL;
|
||||
|
||||
for (gint i = 0; i < n_drawables; i++)
|
||||
drawable_list = g_list_prepend (drawable_list, drawables[i]);
|
||||
|
||||
subimage = pika_image_new_from_drawables (image->pika, drawable_list, FALSE, FALSE);
|
||||
g_list_free (drawable_list);
|
||||
pika_container_remove (image->pika->images, PIKA_OBJECT (subimage));
|
||||
pika_image_resize_to_layers (subimage, context,
|
||||
NULL, NULL, NULL, NULL, NULL);
|
||||
width = pika_image_get_width (subimage);
|
||||
height = pika_image_get_width (subimage);
|
||||
|
||||
pika_pickable_flush (PIKA_PICKABLE (subimage));
|
||||
}
|
||||
else
|
||||
{
|
||||
width = pika_item_get_width (PIKA_ITEM (drawables[0]));
|
||||
height = pika_item_get_height (PIKA_ITEM (drawables[0]));
|
||||
}
|
||||
|
||||
format = pika_babl_format (pika_drawable_is_gray (drawables[0]) ?
|
||||
PIKA_GRAY : PIKA_RGB,
|
||||
PIKA_PRECISION_U8_NON_LINEAR,
|
||||
(subimage && pika_image_has_alpha (subimage)) ||
|
||||
pika_drawable_has_alpha (drawables[0]),
|
||||
NULL);
|
||||
|
||||
pattern = g_object_new (PIKA_TYPE_PATTERN,
|
||||
"name", name,
|
||||
"mime-type", "image/x-pika-pat",
|
||||
NULL);
|
||||
|
||||
pattern->mask = pika_temp_buf_new (width, height, format);
|
||||
|
||||
gegl_buffer_get (subimage != NULL ? pika_pickable_get_buffer (PIKA_PICKABLE (subimage)) :
|
||||
pika_drawable_get_buffer (drawables[0]),
|
||||
GEGL_RECTANGLE (0, 0, width, height), 1.0,
|
||||
format, pika_temp_buf_get_data (pattern->mask),
|
||||
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
|
||||
|
||||
g_clear_object (&subimage);
|
||||
|
||||
return pattern;
|
||||
}
|
41
app/file-data/file-data-pat.h
Normal file
41
app/file-data/file-data-pat.h
Normal file
@ -0,0 +1,41 @@
|
||||
/* PIKA - Photo and Image Kooker Application
|
||||
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
|
||||
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
|
||||
*
|
||||
* Original copyright, applying to most contents (license remains unchanged):
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef __FILE_DATA_PAT_H__
|
||||
#define __FILE_DATA_PAT_H__
|
||||
|
||||
|
||||
PikaValueArray * file_pat_load_invoker (PikaProcedure *procedure,
|
||||
Pika *pika,
|
||||
PikaContext *context,
|
||||
PikaProgress *progress,
|
||||
const PikaValueArray *args,
|
||||
GError **error);
|
||||
|
||||
PikaValueArray * file_pat_save_invoker (PikaProcedure *procedure,
|
||||
Pika *pika,
|
||||
PikaContext *context,
|
||||
PikaProgress *progress,
|
||||
const PikaValueArray *args,
|
||||
GError **error);
|
||||
|
||||
|
||||
#endif /* __FILE_DATA_PAT_H__ */
|
522
app/file-data/file-data.c
Normal file
522
app/file-data/file-data.c
Normal file
@ -0,0 +1,522 @@
|
||||
/* PIKA - Photo and Image Kooker Application
|
||||
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
|
||||
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
|
||||
*
|
||||
* Original copyright, applying to most contents (license remains unchanged):
|
||||
* 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 <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include <gegl.h>
|
||||
|
||||
#include "libpikabase/pikabase.h"
|
||||
|
||||
#include "core/core-types.h"
|
||||
|
||||
#include "core/pika.h"
|
||||
#include "core/pikadrawable.h"
|
||||
#include "core/pikaparamspecs.h"
|
||||
|
||||
#include "plug-in/pikapluginmanager.h"
|
||||
#include "plug-in/pikapluginprocedure.h"
|
||||
|
||||
#include "file-data.h"
|
||||
#include "file-data-gbr.h"
|
||||
#include "file-data-gex.h"
|
||||
#include "file-data-gih.h"
|
||||
#include "file-data-pat.h"
|
||||
|
||||
#include "pika-intl.h"
|
||||
|
||||
|
||||
void
|
||||
file_data_init (Pika *pika)
|
||||
{
|
||||
PikaPlugInProcedure *proc;
|
||||
GFile *file;
|
||||
PikaProcedure *procedure;
|
||||
|
||||
g_return_if_fail (PIKA_IS_PIKA (pika));
|
||||
|
||||
/* file-gbr-load */
|
||||
file = g_file_new_for_path ("file-gbr-load");
|
||||
procedure = pika_plug_in_procedure_new (PIKA_PDB_PROC_TYPE_PLUGIN, file);
|
||||
g_object_unref (file);
|
||||
|
||||
procedure->proc_type = PIKA_PDB_PROC_TYPE_INTERNAL;
|
||||
procedure->marshal_func = file_gbr_load_invoker;
|
||||
|
||||
proc = PIKA_PLUG_IN_PROCEDURE (procedure);
|
||||
proc->menu_label = g_strdup (N_("PIKA brush"));
|
||||
pika_plug_in_procedure_set_icon (proc, PIKA_ICON_TYPE_ICON_NAME,
|
||||
(const guint8 *) "pika-brush",
|
||||
strlen ("pika-brush") + 1,
|
||||
NULL);
|
||||
pika_plug_in_procedure_set_image_types (proc, NULL);
|
||||
pika_plug_in_procedure_set_file_proc (proc, "gbr, gbp", "",
|
||||
"20, string, PIKA");
|
||||
pika_plug_in_procedure_set_mime_types (proc, "image/pika-x-gbr");
|
||||
pika_plug_in_procedure_set_handles_remote (proc);
|
||||
|
||||
pika_object_set_static_name (PIKA_OBJECT (procedure), "file-gbr-load");
|
||||
pika_procedure_set_static_help (procedure,
|
||||
"Loads PIKA brushes",
|
||||
"Loads PIKA brushes (1 or 4 bpp "
|
||||
"and old .gpb format)",
|
||||
NULL);
|
||||
pika_procedure_set_static_attribution (procedure,
|
||||
"Tim Newsome, Jens Lautenbacher, "
|
||||
"Sven Neumann, Michael Natterer",
|
||||
"Tim Newsome, Jens Lautenbacher, "
|
||||
"Sven Neumann, Michael Natterer",
|
||||
"1995-2019");
|
||||
|
||||
pika_procedure_add_argument (procedure,
|
||||
pika_param_spec_enum ("dummy-param",
|
||||
"Dummy Param",
|
||||
"Dummy parameter",
|
||||
PIKA_TYPE_RUN_MODE,
|
||||
PIKA_RUN_INTERACTIVE,
|
||||
PIKA_PARAM_READWRITE));
|
||||
pika_procedure_add_argument (procedure,
|
||||
g_param_spec_object ("file",
|
||||
"File",
|
||||
"The file to load",
|
||||
G_TYPE_FILE,
|
||||
PIKA_PARAM_READWRITE));
|
||||
|
||||
pika_procedure_add_return_value (procedure,
|
||||
pika_param_spec_image ("image",
|
||||
"Image",
|
||||
"Output image",
|
||||
FALSE,
|
||||
PIKA_PARAM_READWRITE));
|
||||
|
||||
pika_plug_in_manager_add_procedure (pika->plug_in_manager, proc);
|
||||
g_object_unref (procedure);
|
||||
|
||||
/* file-gbr-save-internal */
|
||||
file = g_file_new_for_path ("file-gbr-save-internal");
|
||||
procedure = pika_plug_in_procedure_new (PIKA_PDB_PROC_TYPE_PLUGIN, file);
|
||||
g_object_unref (file);
|
||||
|
||||
procedure->proc_type = PIKA_PDB_PROC_TYPE_INTERNAL;
|
||||
procedure->marshal_func = file_gbr_save_invoker;
|
||||
|
||||
proc = PIKA_PLUG_IN_PROCEDURE (procedure);
|
||||
proc->menu_label = g_strdup (N_("PIKA brush"));
|
||||
pika_plug_in_procedure_set_icon (proc, PIKA_ICON_TYPE_ICON_NAME,
|
||||
(const guint8 *) "pika-brush",
|
||||
strlen ("pika-brush") + 1,
|
||||
NULL);
|
||||
|
||||
#if 0
|
||||
/* do not register as file procedure */
|
||||
pika_plug_in_procedure_set_image_types (proc, "RGB*, GRAY*, INDEXED*");
|
||||
pika_plug_in_procedure_set_file_proc (proc, "gbr", "", NULL);
|
||||
pika_plug_in_procedure_set_mime_types (proc, "image/x-pika-gbr");
|
||||
pika_plug_in_procedure_set_handles_remote (proc);
|
||||
#endif
|
||||
|
||||
pika_object_set_static_name (PIKA_OBJECT (procedure),
|
||||
"file-gbr-save-internal");
|
||||
pika_procedure_set_static_help (procedure,
|
||||
"Exports Pika brush file (.GBR)",
|
||||
"Exports Pika brush file (.GBR)",
|
||||
NULL);
|
||||
pika_procedure_set_static_attribution (procedure,
|
||||
"Tim Newsome, Michael Natterer",
|
||||
"Tim Newsome, Michael Natterer",
|
||||
"1995-2019");
|
||||
|
||||
pika_procedure_add_argument (procedure,
|
||||
pika_param_spec_enum ("dummy-param",
|
||||
"Dummy Param",
|
||||
"Dummy parameter",
|
||||
PIKA_TYPE_RUN_MODE,
|
||||
PIKA_RUN_INTERACTIVE,
|
||||
PIKA_PARAM_READWRITE));
|
||||
pika_procedure_add_argument (procedure,
|
||||
pika_param_spec_image ("image",
|
||||
"Image",
|
||||
"Input image",
|
||||
FALSE,
|
||||
PIKA_PARAM_READWRITE));
|
||||
pika_procedure_add_argument (procedure,
|
||||
pika_param_spec_drawable ("drawable",
|
||||
"Drawable",
|
||||
"Active drawable "
|
||||
"of input image",
|
||||
FALSE,
|
||||
PIKA_PARAM_READWRITE));
|
||||
pika_procedure_add_argument (procedure,
|
||||
g_param_spec_object ("file",
|
||||
"File",
|
||||
"The file to export",
|
||||
G_TYPE_FILE,
|
||||
PIKA_PARAM_READWRITE));
|
||||
pika_procedure_add_argument (procedure,
|
||||
g_param_spec_int ("spacing",
|
||||
"spacing",
|
||||
"Spacing of the brush",
|
||||
1, 1000, 10,
|
||||
PIKA_PARAM_READWRITE));
|
||||
pika_procedure_add_argument (procedure,
|
||||
pika_param_spec_string ("name",
|
||||
"name",
|
||||
"The name of the "
|
||||
"brush",
|
||||
FALSE, FALSE, TRUE,
|
||||
"PIKA Brush",
|
||||
PIKA_PARAM_READWRITE));
|
||||
|
||||
pika_plug_in_manager_add_procedure (pika->plug_in_manager, proc);
|
||||
g_object_unref (procedure);
|
||||
|
||||
/* file-gih-load */
|
||||
file = g_file_new_for_path ("file-gih-load");
|
||||
procedure = pika_plug_in_procedure_new (PIKA_PDB_PROC_TYPE_PLUGIN, file);
|
||||
g_object_unref (file);
|
||||
|
||||
procedure->proc_type = PIKA_PDB_PROC_TYPE_INTERNAL;
|
||||
procedure->marshal_func = file_gih_load_invoker;
|
||||
|
||||
proc = PIKA_PLUG_IN_PROCEDURE (procedure);
|
||||
proc->menu_label = g_strdup (N_("PIKA brush (animated)"));
|
||||
pika_plug_in_procedure_set_icon (proc, PIKA_ICON_TYPE_ICON_NAME,
|
||||
(const guint8 *) "pika-brush",
|
||||
strlen ("pika-brush") + 1,
|
||||
NULL);
|
||||
pika_plug_in_procedure_set_image_types (proc, NULL);
|
||||
pika_plug_in_procedure_set_file_proc (proc, "gih", "", "");
|
||||
pika_plug_in_procedure_set_mime_types (proc, "image/pika-x-gih");
|
||||
pika_plug_in_procedure_set_handles_remote (proc);
|
||||
|
||||
pika_object_set_static_name (PIKA_OBJECT (procedure), "file-gih-load");
|
||||
pika_procedure_set_static_help (procedure,
|
||||
"Loads PIKA animated brushes",
|
||||
"This procedure loads a PIKA brush "
|
||||
"pipe as an image.",
|
||||
NULL);
|
||||
pika_procedure_set_static_attribution (procedure,
|
||||
"Tor Lillqvist, Michael Natterer",
|
||||
"Tor Lillqvist, Michael Natterer",
|
||||
"1999-2019");
|
||||
|
||||
pika_procedure_add_argument (procedure,
|
||||
pika_param_spec_enum ("dummy-param",
|
||||
"Dummy Param",
|
||||
"Dummy parameter",
|
||||
PIKA_TYPE_RUN_MODE,
|
||||
PIKA_RUN_INTERACTIVE,
|
||||
PIKA_PARAM_READWRITE));
|
||||
pika_procedure_add_argument (procedure,
|
||||
g_param_spec_object ("file",
|
||||
"File",
|
||||
"The file to load",
|
||||
G_TYPE_FILE,
|
||||
PIKA_PARAM_READWRITE));
|
||||
|
||||
pika_procedure_add_return_value (procedure,
|
||||
pika_param_spec_image ("image",
|
||||
"Image",
|
||||
"Output image",
|
||||
FALSE,
|
||||
PIKA_PARAM_READWRITE));
|
||||
|
||||
pika_plug_in_manager_add_procedure (pika->plug_in_manager, proc);
|
||||
g_object_unref (procedure);
|
||||
|
||||
/* file-gih-save-internal */
|
||||
file = g_file_new_for_path ("file-gih-save-internal");
|
||||
procedure = pika_plug_in_procedure_new (PIKA_PDB_PROC_TYPE_PLUGIN, file);
|
||||
g_object_unref (file);
|
||||
|
||||
procedure->proc_type = PIKA_PDB_PROC_TYPE_INTERNAL;
|
||||
procedure->marshal_func = file_gih_save_invoker;
|
||||
|
||||
proc = PIKA_PLUG_IN_PROCEDURE (procedure);
|
||||
proc->menu_label = g_strdup (N_("PIKA brush (animated)"));
|
||||
pika_plug_in_procedure_set_icon (proc, PIKA_ICON_TYPE_ICON_NAME,
|
||||
(const guint8 *) "pika-brush",
|
||||
strlen ("pika-brush") + 1,
|
||||
NULL);
|
||||
|
||||
#if 0
|
||||
/* do not register as file procedure */
|
||||
pika_plug_in_procedure_set_image_types (proc, "RGB*, GRAY*, INDEXED*");
|
||||
pika_plug_in_procedure_set_file_proc (proc, "gih", "", NULL);
|
||||
pika_plug_in_procedure_set_mime_types (proc, "image/x-pika-gih");
|
||||
pika_plug_in_procedure_set_handles_remote (proc);
|
||||
#endif
|
||||
|
||||
pika_object_set_static_name (PIKA_OBJECT (procedure),
|
||||
"file-gih-save-internal");
|
||||
pika_procedure_set_static_help (procedure,
|
||||
"Exports Pika animated brush file (.gih)",
|
||||
"Exports Pika animated brush file (.gih)",
|
||||
NULL);
|
||||
pika_procedure_set_static_attribution (procedure,
|
||||
"Tor Lillqvist, Michael Natterer",
|
||||
"Tor Lillqvist, Michael Natterer",
|
||||
"1999-2019");
|
||||
|
||||
pika_procedure_add_argument (procedure,
|
||||
pika_param_spec_enum ("dummy-param",
|
||||
"Dummy Param",
|
||||
"Dummy parameter",
|
||||
PIKA_TYPE_RUN_MODE,
|
||||
PIKA_RUN_INTERACTIVE,
|
||||
PIKA_PARAM_READWRITE));
|
||||
pika_procedure_add_argument (procedure,
|
||||
pika_param_spec_image ("image",
|
||||
"Image",
|
||||
"Input image",
|
||||
FALSE,
|
||||
PIKA_PARAM_READWRITE));
|
||||
pika_procedure_add_argument (procedure,
|
||||
g_param_spec_int ("num-drawables",
|
||||
"num drawables",
|
||||
"The number of drawables to save",
|
||||
1, G_MAXINT32, 1,
|
||||
PIKA_PARAM_READWRITE));
|
||||
pika_procedure_add_argument (procedure,
|
||||
pika_param_spec_object_array ("drawables",
|
||||
"drawables",
|
||||
"Drawables to save",
|
||||
PIKA_TYPE_DRAWABLE,
|
||||
PIKA_PARAM_READWRITE | PIKA_PARAM_NO_VALIDATE));
|
||||
pika_procedure_add_argument (procedure,
|
||||
g_param_spec_object ("file",
|
||||
"File",
|
||||
"The file to export",
|
||||
G_TYPE_FILE,
|
||||
PIKA_PARAM_READWRITE));
|
||||
pika_procedure_add_argument (procedure,
|
||||
g_param_spec_int ("spacing",
|
||||
"spacing",
|
||||
"Spacing of the brush",
|
||||
1, 1000, 10,
|
||||
PIKA_PARAM_READWRITE));
|
||||
pika_procedure_add_argument (procedure,
|
||||
pika_param_spec_string ("name",
|
||||
"name",
|
||||
"The name of the "
|
||||
"brush",
|
||||
FALSE, FALSE, TRUE,
|
||||
"PIKA Brush",
|
||||
PIKA_PARAM_READWRITE));
|
||||
pika_procedure_add_argument (procedure,
|
||||
pika_param_spec_string ("params",
|
||||
"params",
|
||||
"The pipe's parameters",
|
||||
FALSE, FALSE, TRUE,
|
||||
NULL,
|
||||
PIKA_PARAM_READWRITE));
|
||||
|
||||
pika_plug_in_manager_add_procedure (pika->plug_in_manager, proc);
|
||||
g_object_unref (procedure);
|
||||
|
||||
/* file-pat-load */
|
||||
file = g_file_new_for_path ("file-pat-load");
|
||||
procedure = pika_plug_in_procedure_new (PIKA_PDB_PROC_TYPE_PLUGIN, file);
|
||||
g_object_unref (file);
|
||||
|
||||
procedure->proc_type = PIKA_PDB_PROC_TYPE_INTERNAL;
|
||||
procedure->marshal_func = file_pat_load_invoker;
|
||||
|
||||
proc = PIKA_PLUG_IN_PROCEDURE (procedure);
|
||||
proc->menu_label = g_strdup (N_("PIKA pattern"));
|
||||
pika_plug_in_procedure_set_icon (proc, PIKA_ICON_TYPE_ICON_NAME,
|
||||
(const guint8 *) "pika-pattern",
|
||||
strlen ("pika-pattern") + 1,
|
||||
NULL);
|
||||
pika_plug_in_procedure_set_image_types (proc, NULL);
|
||||
pika_plug_in_procedure_set_file_proc (proc, "pat", "",
|
||||
"20,string,GPAT");
|
||||
pika_plug_in_procedure_set_mime_types (proc, "image/pika-x-pat");
|
||||
pika_plug_in_procedure_set_handles_remote (proc);
|
||||
|
||||
pika_object_set_static_name (PIKA_OBJECT (procedure), "file-pat-load");
|
||||
pika_procedure_set_static_help (procedure,
|
||||
"Loads PIKA patterns",
|
||||
"Loads PIKA patterns",
|
||||
NULL);
|
||||
pika_procedure_set_static_attribution (procedure,
|
||||
"Tim Newsome, Michael Natterer",
|
||||
"Tim Newsome, Michael Natterer",
|
||||
"1997-2019");
|
||||
|
||||
pika_procedure_add_argument (procedure,
|
||||
pika_param_spec_enum ("dummy-param",
|
||||
"Dummy Param",
|
||||
"Dummy parameter",
|
||||
PIKA_TYPE_RUN_MODE,
|
||||
PIKA_RUN_INTERACTIVE,
|
||||
PIKA_PARAM_READWRITE));
|
||||
pika_procedure_add_argument (procedure,
|
||||
g_param_spec_object ("file",
|
||||
"File",
|
||||
"The file to load",
|
||||
G_TYPE_FILE,
|
||||
PIKA_PARAM_READWRITE));
|
||||
pika_procedure_add_return_value (procedure,
|
||||
pika_param_spec_image ("image",
|
||||
"Image",
|
||||
"Output image",
|
||||
FALSE,
|
||||
PIKA_PARAM_READWRITE));
|
||||
|
||||
pika_plug_in_manager_add_procedure (pika->plug_in_manager, proc);
|
||||
g_object_unref (procedure);
|
||||
|
||||
/* file-pat-save-internal */
|
||||
file = g_file_new_for_path ("file-pat-save-internal");
|
||||
procedure = pika_plug_in_procedure_new (PIKA_PDB_PROC_TYPE_PLUGIN, file);
|
||||
g_object_unref (file);
|
||||
|
||||
procedure->proc_type = PIKA_PDB_PROC_TYPE_INTERNAL;
|
||||
procedure->marshal_func = file_pat_save_invoker;
|
||||
|
||||
proc = PIKA_PLUG_IN_PROCEDURE (procedure);
|
||||
proc->menu_label = g_strdup (N_("PIKA pattern"));
|
||||
pika_plug_in_procedure_set_icon (proc, PIKA_ICON_TYPE_ICON_NAME,
|
||||
(const guint8 *) "pika-pattern",
|
||||
strlen ("pika-pattern") + 1,
|
||||
NULL);
|
||||
|
||||
#if 0
|
||||
/* do not register as file procedure */
|
||||
pika_plug_in_procedure_set_image_types (proc, "RGB*, GRAY*, INDEXED*");
|
||||
pika_plug_in_procedure_set_file_proc (proc, "pat", "", NULL);
|
||||
pika_plug_in_procedure_set_mime_types (proc, "image/x-pika-pat");
|
||||
pika_plug_in_procedure_set_handles_remote (proc);
|
||||
#endif
|
||||
|
||||
pika_object_set_static_name (PIKA_OBJECT (procedure),
|
||||
"file-pat-save-internal");
|
||||
pika_procedure_set_static_help (procedure,
|
||||
"Exports Pika pattern file (.PAT)",
|
||||
"Exports Pika pattern file (.PAT)",
|
||||
NULL);
|
||||
pika_procedure_set_static_attribution (procedure,
|
||||
"Tim Newsome, Michael Natterer",
|
||||
"Tim Newsome, Michael Natterer",
|
||||
"1995-2019");
|
||||
|
||||
pika_procedure_add_argument (procedure,
|
||||
pika_param_spec_enum ("dummy-param",
|
||||
"Dummy Param",
|
||||
"Dummy parameter",
|
||||
PIKA_TYPE_RUN_MODE,
|
||||
PIKA_RUN_INTERACTIVE,
|
||||
PIKA_PARAM_READWRITE));
|
||||
pika_procedure_add_argument (procedure,
|
||||
pika_param_spec_image ("image",
|
||||
"Image",
|
||||
"Input image",
|
||||
FALSE,
|
||||
PIKA_PARAM_READWRITE));
|
||||
pika_procedure_add_argument (procedure,
|
||||
g_param_spec_int ("n-drawables",
|
||||
"Num drawables",
|
||||
"Number of drawables",
|
||||
1, G_MAXINT, 1,
|
||||
PIKA_PARAM_READWRITE));
|
||||
pika_procedure_add_argument (procedure,
|
||||
pika_param_spec_object_array ("drawables",
|
||||
"Drawables",
|
||||
"Selected drawables",
|
||||
PIKA_TYPE_DRAWABLE,
|
||||
PIKA_PARAM_READWRITE | PIKA_PARAM_NO_VALIDATE));
|
||||
pika_procedure_add_argument (procedure,
|
||||
g_param_spec_object ("file",
|
||||
"File",
|
||||
"The file to export",
|
||||
G_TYPE_FILE,
|
||||
PIKA_PARAM_READWRITE));
|
||||
pika_procedure_add_argument (procedure,
|
||||
pika_param_spec_string ("name",
|
||||
"name",
|
||||
"The name of the "
|
||||
"pattern",
|
||||
FALSE, FALSE, TRUE,
|
||||
"PIKA Pattern",
|
||||
PIKA_PARAM_READWRITE));
|
||||
|
||||
pika_plug_in_manager_add_procedure (pika->plug_in_manager, proc);
|
||||
g_object_unref (procedure);
|
||||
|
||||
/* file-gex-load */
|
||||
file = g_file_new_for_path ("file-gex-load");
|
||||
procedure = pika_plug_in_procedure_new (PIKA_PDB_PROC_TYPE_PLUGIN, file);
|
||||
g_object_unref (file);
|
||||
|
||||
procedure->proc_type = PIKA_PDB_PROC_TYPE_INTERNAL;
|
||||
procedure->marshal_func = file_gex_load_invoker;
|
||||
|
||||
proc = PIKA_PLUG_IN_PROCEDURE (procedure);
|
||||
proc->menu_label = g_strdup (N_("PIKA extension"));
|
||||
pika_plug_in_procedure_set_icon (proc, PIKA_ICON_TYPE_ICON_NAME,
|
||||
(const guint8 *) "pika-plugin",
|
||||
strlen ("pika-plugin") + 1,
|
||||
NULL);
|
||||
pika_plug_in_procedure_set_file_proc (proc, "gex", "",
|
||||
"20, string, PIKA");
|
||||
pika_plug_in_procedure_set_generic_file_proc (proc, TRUE);
|
||||
pika_plug_in_procedure_set_mime_types (proc, "image/pika-x-gex");
|
||||
pika_plug_in_procedure_set_handles_remote (proc);
|
||||
|
||||
pika_object_set_static_name (PIKA_OBJECT (procedure), "file-gex-load");
|
||||
pika_procedure_set_static_help (procedure,
|
||||
"Loads PIKA extension",
|
||||
"Loads PIKA extension",
|
||||
NULL);
|
||||
pika_procedure_set_static_attribution (procedure,
|
||||
"Jehan", "Jehan", "2019");
|
||||
|
||||
pika_procedure_add_argument (procedure,
|
||||
pika_param_spec_enum ("dummy-param",
|
||||
"Dummy Param",
|
||||
"Dummy parameter",
|
||||
PIKA_TYPE_RUN_MODE,
|
||||
PIKA_RUN_INTERACTIVE,
|
||||
PIKA_PARAM_READWRITE));
|
||||
pika_procedure_add_argument (procedure,
|
||||
g_param_spec_object ("file",
|
||||
"File",
|
||||
"The file to load",
|
||||
G_TYPE_FILE,
|
||||
PIKA_PARAM_READWRITE));
|
||||
|
||||
pika_procedure_add_return_value (procedure,
|
||||
pika_param_spec_string ("extension-id",
|
||||
"ID of installed extension",
|
||||
"Identifier of the newly installed extension",
|
||||
FALSE, TRUE, FALSE, NULL,
|
||||
PIKA_PARAM_READWRITE));
|
||||
|
||||
pika_plug_in_manager_add_procedure (pika->plug_in_manager, proc);
|
||||
g_object_unref (procedure);
|
||||
}
|
||||
|
||||
void
|
||||
file_data_exit (Pika *pika)
|
||||
{
|
||||
g_return_if_fail (PIKA_IS_PIKA (pika));
|
||||
}
|
30
app/file-data/file-data.h
Normal file
30
app/file-data/file-data.h
Normal file
@ -0,0 +1,30 @@
|
||||
/* PIKA - Photo and Image Kooker Application
|
||||
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
|
||||
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
|
||||
*
|
||||
* Original copyright, applying to most contents (license remains unchanged):
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef __FILE_DATA_H__
|
||||
#define __FILE_DATA_H__
|
||||
|
||||
|
||||
void file_data_init (Pika *pika);
|
||||
void file_data_exit (Pika *pika);
|
||||
|
||||
|
||||
#endif /* __FILE_DATA_H__ */
|
21
app/file-data/meson.build
Normal file
21
app/file-data/meson.build
Normal file
@ -0,0 +1,21 @@
|
||||
|
||||
libappfiledata_sources = [
|
||||
'file-data-gbr.c',
|
||||
'file-data-gex.c',
|
||||
'file-data-gih.c',
|
||||
'file-data-pat.c',
|
||||
'file-data.c',
|
||||
]
|
||||
|
||||
libappfiledata = static_library('appfiledata',
|
||||
libappfiledata_sources,
|
||||
include_directories: [ rootInclude, rootAppInclude, ],
|
||||
c_args: '-DG_LOG_DOMAIN="Pika-File-Data"',
|
||||
dependencies: [
|
||||
appstream_glib,
|
||||
cairo,
|
||||
gdk_pixbuf,
|
||||
gegl,
|
||||
libarchive,
|
||||
],
|
||||
)
|
Reference in New Issue
Block a user