289 lines
8.2 KiB
C
289 lines
8.2 KiB
C
|
/* 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
|
||
|
*
|
||
|
* pika_brush_generated module Copyright 1998 Jay Cox <jaycox@earthlink.net>
|
||
|
*
|
||
|
* 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 <gdk-pixbuf/gdk-pixbuf.h>
|
||
|
#include <gegl.h>
|
||
|
|
||
|
#include "libpikabase/pikabase.h"
|
||
|
|
||
|
#include "core-types.h"
|
||
|
|
||
|
#include "pika-utils.h"
|
||
|
#include "pikabrushgenerated.h"
|
||
|
#include "pikabrushgenerated-load.h"
|
||
|
|
||
|
#include "pika-intl.h"
|
||
|
|
||
|
|
||
|
GList *
|
||
|
pika_brush_generated_load (PikaContext *context,
|
||
|
GFile *file,
|
||
|
GInputStream *input,
|
||
|
GError **error)
|
||
|
{
|
||
|
PikaBrush *brush;
|
||
|
GDataInputStream *data_input;
|
||
|
gchar *string;
|
||
|
gsize string_len;
|
||
|
gint linenum;
|
||
|
gchar *name = NULL;
|
||
|
PikaBrushGeneratedShape shape = PIKA_BRUSH_GENERATED_CIRCLE;
|
||
|
gboolean have_shape = FALSE;
|
||
|
gint spikes = 2;
|
||
|
gdouble spacing;
|
||
|
gdouble radius;
|
||
|
gdouble hardness;
|
||
|
gdouble aspect_ratio;
|
||
|
gdouble angle;
|
||
|
|
||
|
g_return_val_if_fail (G_IS_FILE (file), NULL);
|
||
|
g_return_val_if_fail (G_IS_INPUT_STREAM (input), NULL);
|
||
|
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||
|
|
||
|
data_input = g_data_input_stream_new (input);
|
||
|
|
||
|
/* make sure the file we are reading is the right type */
|
||
|
linenum = 1;
|
||
|
string_len = 256;
|
||
|
string = pika_data_input_stream_read_line_always (data_input, &string_len,
|
||
|
NULL, error);
|
||
|
if (! string)
|
||
|
goto failed;
|
||
|
|
||
|
if (! g_str_has_prefix (string, "PIKA-VBR"))
|
||
|
{
|
||
|
g_set_error (error, PIKA_DATA_ERROR, PIKA_DATA_ERROR_READ,
|
||
|
_("Not a PIKA brush file."));
|
||
|
g_free (string);
|
||
|
goto failed;
|
||
|
}
|
||
|
|
||
|
g_free (string);
|
||
|
|
||
|
/* make sure we are reading a compatible version */
|
||
|
linenum++;
|
||
|
string_len = 256;
|
||
|
string = pika_data_input_stream_read_line_always (data_input, &string_len,
|
||
|
NULL, error);
|
||
|
if (! string)
|
||
|
goto failed;
|
||
|
|
||
|
if (! g_str_has_prefix (string, "1.0"))
|
||
|
{
|
||
|
if (! g_str_has_prefix (string, "1.5"))
|
||
|
{
|
||
|
g_set_error (error, PIKA_DATA_ERROR, PIKA_DATA_ERROR_READ,
|
||
|
_("Unknown PIKA brush version."));
|
||
|
g_free (string);
|
||
|
goto failed;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
have_shape = TRUE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
g_free (string);
|
||
|
|
||
|
/* read name */
|
||
|
linenum++;
|
||
|
string_len = 256;
|
||
|
string = pika_data_input_stream_read_line_always (data_input, &string_len,
|
||
|
NULL, error);
|
||
|
if (! string)
|
||
|
goto failed;
|
||
|
|
||
|
g_strstrip (string);
|
||
|
|
||
|
/* the empty string is not an allowed name */
|
||
|
if (strlen (string) < 1)
|
||
|
{
|
||
|
name = g_strdup (_("Untitled"));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
name = pika_any_to_utf8 (string, -1,
|
||
|
_("Invalid UTF-8 string in brush file '%s'."),
|
||
|
pika_file_get_utf8_name (file));
|
||
|
}
|
||
|
|
||
|
g_free (string);
|
||
|
|
||
|
if (have_shape)
|
||
|
{
|
||
|
GEnumClass *enum_class;
|
||
|
GEnumValue *shape_val;
|
||
|
|
||
|
enum_class = g_type_class_peek (PIKA_TYPE_BRUSH_GENERATED_SHAPE);
|
||
|
|
||
|
/* read shape */
|
||
|
linenum++;
|
||
|
string_len = 256;
|
||
|
string = pika_data_input_stream_read_line_always (data_input, &string_len,
|
||
|
NULL, error);
|
||
|
if (! string)
|
||
|
goto failed;
|
||
|
|
||
|
g_strstrip (string);
|
||
|
shape_val = g_enum_get_value_by_nick (enum_class, string);
|
||
|
|
||
|
if (! shape_val)
|
||
|
{
|
||
|
g_set_error (error, PIKA_DATA_ERROR, PIKA_DATA_ERROR_READ,
|
||
|
_("Unknown PIKA brush shape."));
|
||
|
g_free (string);
|
||
|
goto failed;
|
||
|
}
|
||
|
|
||
|
g_free (string);
|
||
|
|
||
|
shape = shape_val->value;
|
||
|
}
|
||
|
|
||
|
/* read brush spacing */
|
||
|
linenum++;
|
||
|
string_len = 256;
|
||
|
string = pika_data_input_stream_read_line_always (data_input, &string_len,
|
||
|
NULL, error);
|
||
|
if (! string)
|
||
|
goto failed;
|
||
|
if (! pika_ascii_strtod (string, NULL, &spacing))
|
||
|
{
|
||
|
g_set_error (error, PIKA_DATA_ERROR, PIKA_DATA_ERROR_READ,
|
||
|
_("Invalid brush spacing."));
|
||
|
g_free (string);
|
||
|
goto failed;
|
||
|
}
|
||
|
g_free (string);
|
||
|
|
||
|
|
||
|
/* read brush radius */
|
||
|
linenum++;
|
||
|
string_len = 256;
|
||
|
string = pika_data_input_stream_read_line_always (data_input, &string_len,
|
||
|
NULL, error);
|
||
|
if (! string)
|
||
|
goto failed;
|
||
|
if (! pika_ascii_strtod (string, NULL, &radius))
|
||
|
{
|
||
|
g_set_error (error, PIKA_DATA_ERROR, PIKA_DATA_ERROR_READ,
|
||
|
_("Invalid brush radius."));
|
||
|
g_free (string);
|
||
|
goto failed;
|
||
|
}
|
||
|
g_free (string);
|
||
|
|
||
|
if (have_shape)
|
||
|
{
|
||
|
/* read number of spikes */
|
||
|
linenum++;
|
||
|
string_len = 256;
|
||
|
string = pika_data_input_stream_read_line_always (data_input, &string_len,
|
||
|
NULL, error);
|
||
|
if (! string)
|
||
|
goto failed;
|
||
|
if (! pika_ascii_strtoi (string, NULL, 10, &spikes) ||
|
||
|
spikes < 2 || spikes > 20)
|
||
|
{
|
||
|
g_set_error (error, PIKA_DATA_ERROR, PIKA_DATA_ERROR_READ,
|
||
|
_("Invalid brush spike count."));
|
||
|
g_free (string);
|
||
|
goto failed;
|
||
|
}
|
||
|
g_free (string);
|
||
|
}
|
||
|
|
||
|
/* read brush hardness */
|
||
|
linenum++;
|
||
|
string_len = 256;
|
||
|
string = pika_data_input_stream_read_line_always (data_input, &string_len,
|
||
|
NULL, error);
|
||
|
if (! string)
|
||
|
goto failed;
|
||
|
if (! pika_ascii_strtod (string, NULL, &hardness))
|
||
|
{
|
||
|
g_set_error (error, PIKA_DATA_ERROR, PIKA_DATA_ERROR_READ,
|
||
|
_("Invalid brush hardness."));
|
||
|
g_free (string);
|
||
|
goto failed;
|
||
|
}
|
||
|
g_free (string);
|
||
|
|
||
|
/* read brush aspect_ratio */
|
||
|
linenum++;
|
||
|
string_len = 256;
|
||
|
string = pika_data_input_stream_read_line_always (data_input, &string_len,
|
||
|
NULL, error);
|
||
|
if (! string)
|
||
|
goto failed;
|
||
|
if (! pika_ascii_strtod (string, NULL, &aspect_ratio))
|
||
|
{
|
||
|
g_set_error (error, PIKA_DATA_ERROR, PIKA_DATA_ERROR_READ,
|
||
|
_("Invalid brush aspect ratio."));
|
||
|
g_free (string);
|
||
|
goto failed;
|
||
|
}
|
||
|
g_free (string);
|
||
|
|
||
|
/* read brush angle */
|
||
|
linenum++;
|
||
|
string_len = 256;
|
||
|
string = pika_data_input_stream_read_line_always (data_input, &string_len,
|
||
|
NULL, error);
|
||
|
if (! string)
|
||
|
goto failed;
|
||
|
if (! pika_ascii_strtod (string, NULL, &angle))
|
||
|
{
|
||
|
g_set_error (error, PIKA_DATA_ERROR, PIKA_DATA_ERROR_READ,
|
||
|
_("Invalid brush angle."));
|
||
|
g_free (string);
|
||
|
goto failed;
|
||
|
}
|
||
|
g_free (string);
|
||
|
|
||
|
g_object_unref (data_input);
|
||
|
|
||
|
brush = PIKA_BRUSH (pika_brush_generated_new (name, shape, radius, spikes,
|
||
|
hardness, aspect_ratio, angle));
|
||
|
g_free (name);
|
||
|
|
||
|
pika_brush_set_spacing (brush, spacing);
|
||
|
|
||
|
return g_list_prepend (NULL, brush);
|
||
|
|
||
|
failed:
|
||
|
|
||
|
g_object_unref (data_input);
|
||
|
|
||
|
if (name)
|
||
|
g_free (name);
|
||
|
|
||
|
g_prefix_error (error, _("In line %d of brush file: "), linenum);
|
||
|
|
||
|
return NULL;
|
||
|
}
|