gimpbrushgenerated-load.c 7.92 KB
Newer Older
1
/* GIMP - The GNU Image Manipulation Program
2 3 4 5
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
 * gimp_brush_generated module Copyright 1998 Jay Cox <jaycox@earthlink.net>
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; either version 3 of the License, or
9 10 11 12 13 14 15 16
 * (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
17
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
18
 */
19

20 21
#include "config.h"

22
#include <stdlib.h>
23

24 25
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gegl.h>
Sven Neumann's avatar
Sven Neumann committed
26

27
#include "libgimpbase/gimpbase.h"
28

29
#include "core-types.h"
Sven Neumann's avatar
Sven Neumann committed
30

31
#include "gimp-utils.h"
32
#include "gimpbrushgenerated.h"
33
#include "gimpbrushgenerated-load.h"
34

35
#include "gimp-intl.h"
36

37

38
GList *
39 40 41 42
gimp_brush_generated_load (GimpContext   *context,
                           GFile         *file,
                           GInputStream  *input,
                           GError       **error)
43
{
Sven Neumann's avatar
Sven Neumann committed
44
  GimpBrush               *brush;
45 46 47
  GDataInputStream        *data_input;
  gchar                   *string;
  gsize                    string_len;
48
  gint                     linenum;
49 50
  gchar                   *name       = NULL;
  GimpBrushGeneratedShape  shape      = GIMP_BRUSH_GENERATED_CIRCLE;
51
  gboolean                 have_shape = FALSE;
52
  gint                     spikes     = 2;
53 54 55 56 57
  gdouble                  spacing;
  gdouble                  radius;
  gdouble                  hardness;
  gdouble                  aspect_ratio;
  gdouble                  angle;
58

59
  g_return_val_if_fail (G_IS_FILE (file), NULL);
60
  g_return_val_if_fail (G_IS_INPUT_STREAM (input), NULL);
61
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
Michael Natterer's avatar
Michael Natterer committed
62

63
  data_input = g_data_input_stream_new (input);
64 65

  /* make sure the file we are reading is the right type */
66
  linenum = 1;
67
  string_len = 256;
68 69
  string = gimp_data_input_stream_read_line_always (data_input, &string_len,
                                                    NULL, error);
70
  if (! string)
71
    goto failed;
72

73
  if (! g_str_has_prefix (string, "GIMP-VBR"))
74 75
    {
      g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
76
                   _("Not a GIMP brush file."));
77
      g_free (string);
78
      goto failed;
79
    }
80

81 82
  g_free (string);

83
  /* make sure we are reading a compatible version */
84
  linenum++;
85
  string_len = 256;
86 87
  string = gimp_data_input_stream_read_line_always (data_input, &string_len,
                                                    NULL, error);
88
  if (! string)
89 90
    goto failed;

91
  if (! g_str_has_prefix (string, "1.0"))
92
    {
93
      if (! g_str_has_prefix (string, "1.5"))
94 95
        {
          g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
96
                       _("Unknown GIMP brush version."));
97
          g_free (string);
98
          goto failed;
99 100 101 102 103
        }
      else
        {
          have_shape = TRUE;
        }
104
    }
105

106 107
  g_free (string);

Michael Natterer's avatar
Michael Natterer committed
108
  /* read name */
109
  linenum++;
110
  string_len = 256;
111 112
  string = gimp_data_input_stream_read_line_always (data_input, &string_len,
                                                    NULL, error);
113
  if (! string)
114
    goto failed;
115

116
  g_strstrip (string);
117 118 119

  /* the empty string is not an allowed name */
  if (strlen (string) < 1)
Simon Budig's avatar
Simon Budig committed
120 121 122 123 124 125 126 127 128
    {
      name = g_strdup (_("Untitled"));
    }
  else
    {
      name = gimp_any_to_utf8 (string, -1,
                               _("Invalid UTF-8 string in brush file '%s'."),
                               gimp_file_get_utf8_name (file));
    }
129

130 131
  g_free (string);

132 133 134 135 136 137 138 139
  if (have_shape)
    {
      GEnumClass *enum_class;
      GEnumValue *shape_val;

      enum_class = g_type_class_peek (GIMP_TYPE_BRUSH_GENERATED_SHAPE);

      /* read shape */
140
      linenum++;
141
      string_len = 256;
142 143
      string = gimp_data_input_stream_read_line_always (data_input, &string_len,
                                                        NULL, error);
144
      if (! string)
145 146 147 148 149
        goto failed;

      g_strstrip (string);
      shape_val = g_enum_get_value_by_nick (enum_class, string);

150
      if (! shape_val)
151 152
        {
          g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
153
                       _("Unknown GIMP brush shape."));
154
          g_free (string);
155
          goto failed;
156 157
        }

158 159
      g_free (string);

160 161 162
      shape = shape_val->value;
    }

163
  /* read brush spacing */
164
  linenum++;
165
  string_len = 256;
166 167
  string = gimp_data_input_stream_read_line_always (data_input, &string_len,
                                                    NULL, error);
168
  if (! string)
169
    goto failed;
170 171 172 173 174 175 176
  if (! gimp_ascii_strtod (string, NULL, &spacing))
    {
      g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
                   _("Invalid brush spacing."));
      g_free (string);
      goto failed;
    }
177
  g_free (string);
178

179

180
  /* read brush radius */
181
  linenum++;
182
  string_len = 256;
183 184
  string = gimp_data_input_stream_read_line_always (data_input, &string_len,
                                                    NULL, error);
185
  if (! string)
186
    goto failed;
187 188 189 190 191 192 193
  if (! gimp_ascii_strtod (string, NULL, &radius))
    {
      g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
                   _("Invalid brush radius."));
      g_free (string);
      goto failed;
    }
194
  g_free (string);
195

196 197
  if (have_shape)
    {
198 199
      /* read number of spikes */
      linenum++;
200
      string_len = 256;
201 202
      string = gimp_data_input_stream_read_line_always (data_input, &string_len,
                                                        NULL, error);
203
      if (! string)
204
        goto failed;
205 206 207 208 209 210 211 212
      if (! gimp_ascii_strtoi (string, NULL, 10, &spikes) ||
          spikes < 2 || spikes > 20)
        {
          g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
                       _("Invalid brush spike count."));
          g_free (string);
          goto failed;
        }
213
      g_free (string);
214 215
    }

216
  /* read brush hardness */
217
  linenum++;
218
  string_len = 256;
219 220
  string = gimp_data_input_stream_read_line_always (data_input, &string_len,
                                                    NULL, error);
221
  if (! string)
222
    goto failed;
223 224 225 226 227 228 229
  if (! gimp_ascii_strtod (string, NULL, &hardness))
    {
      g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
                   _("Invalid brush hardness."));
      g_free (string);
      goto failed;
    }
230
  g_free (string);
231 232

  /* read brush aspect_ratio */
233
  linenum++;
234
  string_len = 256;
235 236
  string = gimp_data_input_stream_read_line_always (data_input, &string_len,
                                                    NULL, error);
237
  if (! string)
238
    goto failed;
239 240 241 242 243 244 245
  if (! gimp_ascii_strtod (string, NULL, &aspect_ratio))
    {
      g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
                   _("Invalid brush aspect ratio."));
      g_free (string);
      goto failed;
    }
246
  g_free (string);
247 248

  /* read brush angle */
249
  linenum++;
250
  string_len = 256;
251 252
  string = gimp_data_input_stream_read_line_always (data_input, &string_len,
                                                    NULL, error);
253
  if (! string)
254
    goto failed;
255 256 257 258 259 260 261
  if (! gimp_ascii_strtod (string, NULL, &angle))
    {
      g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
                   _("Invalid brush angle."));
      g_free (string);
      goto failed;
    }
262
  g_free (string);
263

264
  g_object_unref (data_input);
265

Sven Neumann's avatar
Sven Neumann committed
266 267
  brush = GIMP_BRUSH (gimp_brush_generated_new (name, shape, radius, spikes,
                                                hardness, aspect_ratio, angle));
268 269
  g_free (name);

270
  gimp_brush_set_spacing (brush, spacing);
271

272
  return g_list_prepend (NULL, brush);
273 274 275

 failed:

276
  g_object_unref (data_input);
277

278 279 280
  if (name)
    g_free (name);

281
  g_prefix_error (error, _("In line %d of brush file: "), linenum);
282

283
  return NULL;
284
}