~ubuntu-branches/ubuntu/breezy/gimp/breezy

« back to all changes in this revision

Viewing changes to app/xcf/xcf-load.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2005-10-04 19:04:46 UTC
  • Revision ID: james.westby@ubuntu.com-20051004190446-ukh32kwk56s4sjhu
Tags: upstream-2.2.8
ImportĀ upstreamĀ versionĀ 2.2.8

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* The GIMP -- an image manipulation program
 
2
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or modify
 
5
 * it under the terms of the GNU General Public License as published by
 
6
 * the Free Software Foundation; either version 2 of the License, or
 
7
 * (at your option) any later version.
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * GNU General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software
 
16
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
17
 */
 
18
 
 
19
#include "config.h"
 
20
 
 
21
#include <stdio.h>
 
22
#include <string.h> /* strcmp, memcmp */
 
23
 
 
24
#include <glib-object.h>
 
25
 
 
26
#include "libgimpbase/gimpbase.h"
 
27
#include "libgimpcolor/gimpcolor.h"
 
28
 
 
29
#include "core/core-types.h"
 
30
 
 
31
#include "base/tile.h"
 
32
#include "base/tile-manager.h"
 
33
#include "base/tile-manager-private.h"
 
34
 
 
35
#include "config/gimpcoreconfig.h"
 
36
 
 
37
#include "core/gimp.h"
 
38
#include "core/gimpcontainer.h"
 
39
#include "core/gimpdrawable.h"
 
40
#include "core/gimpgrid.h"
 
41
#include "core/gimpimage.h"
 
42
#include "core/gimpimage-grid.h"
 
43
#include "core/gimpimage-guides.h"
 
44
#include "core/gimplayer.h"
 
45
#include "core/gimplayer-floating-sel.h"
 
46
#include "core/gimplayermask.h"
 
47
#include "core/gimpparasitelist.h"
 
48
#include "core/gimpselection.h"
 
49
#include "core/gimptemplate.h"
 
50
#include "core/gimpunit.h"
 
51
 
 
52
#include "text/gimptextlayer.h"
 
53
#include "text/gimptextlayer-xcf.h"
 
54
 
 
55
#include "vectors/gimpanchor.h"
 
56
#include "vectors/gimpstroke.h"
 
57
#include "vectors/gimpbezierstroke.h"
 
58
#include "vectors/gimpvectors.h"
 
59
#include "vectors/gimpvectors-compat.h"
 
60
 
 
61
#include "xcf-private.h"
 
62
#include "xcf-load.h"
 
63
#include "xcf-read.h"
 
64
#include "xcf-seek.h"
 
65
 
 
66
#include "gimp-intl.h"
 
67
 
 
68
/* #define GIMP_XCF_PATH_DEBUG */
 
69
 
 
70
static gboolean        xcf_load_image_props   (XcfInfo      *info,
 
71
                                               GimpImage    *gimage);
 
72
static gboolean        xcf_load_layer_props   (XcfInfo      *info,
 
73
                                               GimpImage    *gimage,
 
74
                                               GimpLayer    *layer,
 
75
                                               gboolean     *apply_mask,
 
76
                                               gboolean     *edit_mask,
 
77
                                               gboolean     *show_mask,
 
78
                                               guint32      *text_layer_flags);
 
79
static gboolean        xcf_load_channel_props (XcfInfo      *info,
 
80
                                               GimpImage    *gimage,
 
81
                                               GimpChannel **channel);
 
82
static gboolean        xcf_load_prop          (XcfInfo      *info,
 
83
                                               PropType     *prop_type,
 
84
                                               guint32      *prop_size);
 
85
static GimpLayer     * xcf_load_layer         (XcfInfo      *info,
 
86
                                               GimpImage    *gimage);
 
87
static GimpChannel   * xcf_load_channel       (XcfInfo      *info,
 
88
                                               GimpImage    *gimage);
 
89
static GimpLayerMask * xcf_load_layer_mask    (XcfInfo      *info,
 
90
                                               GimpImage    *gimage);
 
91
static gboolean        xcf_load_hierarchy     (XcfInfo      *info,
 
92
                                               TileManager  *tiles);
 
93
static gboolean        xcf_load_level         (XcfInfo      *info,
 
94
                                               TileManager  *tiles);
 
95
static gboolean        xcf_load_tile          (XcfInfo      *info,
 
96
                                               Tile         *tile);
 
97
static gboolean        xcf_load_tile_rle      (XcfInfo      *info,
 
98
                                               Tile         *tile,
 
99
                                               gint          data_length);
 
100
static GimpParasite  * xcf_load_parasite      (XcfInfo      *info);
 
101
static gboolean        xcf_load_old_paths     (XcfInfo      *info,
 
102
                                               GimpImage    *gimage);
 
103
static gboolean        xcf_load_old_path      (XcfInfo      *info,
 
104
                                               GimpImage    *gimage);
 
105
static gboolean        xcf_load_vectors       (XcfInfo      *info,
 
106
                                               GimpImage    *gimage);
 
107
static gboolean        xcf_load_vector        (XcfInfo      *info,
 
108
                                               GimpImage    *gimage);
 
109
 
 
110
#ifdef SWAP_FROM_FILE
 
111
static gboolean        xcf_swap_func          (gint          fd,
 
112
                                               Tile         *tile,
 
113
                                               gint          cmd,
 
114
                                               gpointer      user_data);
 
115
#endif
 
116
 
 
117
 
 
118
GimpImage *
 
119
xcf_load_image (Gimp    *gimp,
 
120
                XcfInfo *info)
 
121
{
 
122
  GimpImage    *gimage;
 
123
  GimpLayer    *layer;
 
124
  GimpChannel  *channel;
 
125
  GimpParasite *parasite;
 
126
  guint32       saved_pos;
 
127
  guint32       offset;
 
128
  gint          width;
 
129
  gint          height;
 
130
  gint          image_type;
 
131
  gint          num_successful_elements = 0;
 
132
 
 
133
  /* read in the image width, height and type */
 
134
  info->cp += xcf_read_int32 (info->fp, (guint32 *) &width, 1);
 
135
  info->cp += xcf_read_int32 (info->fp, (guint32 *) &height, 1);
 
136
  info->cp += xcf_read_int32 (info->fp, (guint32 *) &image_type, 1);
 
137
 
 
138
  gimage = gimp_create_image (gimp,
 
139
                              width, height,
 
140
                              image_type,
 
141
                              FALSE);
 
142
 
 
143
  /* read the image properties */
 
144
  if (!xcf_load_image_props (info, gimage))
 
145
    goto hard_error;
 
146
 
 
147
  /* check for a GimpGrid parasite */
 
148
  parasite = gimp_image_parasite_find (GIMP_IMAGE (gimage),
 
149
                                       gimp_grid_parasite_name ());
 
150
  if (parasite)
 
151
    {
 
152
      GimpGrid *grid = gimp_grid_from_parasite (parasite);
 
153
 
 
154
      if (grid)
 
155
        {
 
156
          gimp_parasite_list_remove (GIMP_IMAGE (gimage)->parasites,
 
157
                                     gimp_parasite_name (parasite));
 
158
 
 
159
          gimp_image_set_grid (GIMP_IMAGE (gimage), grid, FALSE);
 
160
        }
 
161
    }
 
162
 
 
163
 
 
164
  while (TRUE)
 
165
    {
 
166
      /* read in the offset of the next layer */
 
167
      info->cp += xcf_read_int32 (info->fp, &offset, 1);
 
168
 
 
169
      /* if the offset is 0 then we are at the end
 
170
       *  of the layer list.
 
171
       */
 
172
      if (offset == 0)
 
173
        break;
 
174
 
 
175
      /* save the current position as it is where the
 
176
       *  next layer offset is stored.
 
177
       */
 
178
      saved_pos = info->cp;
 
179
 
 
180
      /* seek to the layer offset */
 
181
      if (! xcf_seek_pos (info, offset, NULL))
 
182
        goto error;
 
183
 
 
184
      /* read in the layer */
 
185
      layer = xcf_load_layer (info, gimage);
 
186
      if (!layer)
 
187
        goto error;
 
188
 
 
189
      num_successful_elements++;
 
190
 
 
191
      /* add the layer to the image if its not the floating selection */
 
192
      if (layer != info->floating_sel)
 
193
        gimp_image_add_layer (gimage, layer,
 
194
                              gimp_container_num_children (gimage->layers));
 
195
 
 
196
      /* restore the saved position so we'll be ready to
 
197
       *  read the next offset.
 
198
       */
 
199
      if (! xcf_seek_pos (info, saved_pos, NULL))
 
200
        goto error;
 
201
    }
 
202
 
 
203
  while (TRUE)
 
204
    {
 
205
      /* read in the offset of the next channel */
 
206
      info->cp += xcf_read_int32 (info->fp, &offset, 1);
 
207
 
 
208
      /* if the offset is 0 then we are at the end
 
209
       *  of the channel list.
 
210
       */
 
211
      if (offset == 0)
 
212
        break;
 
213
 
 
214
      /* save the current position as it is where the
 
215
       *  next channel offset is stored.
 
216
       */
 
217
      saved_pos = info->cp;
 
218
 
 
219
      /* seek to the channel offset */
 
220
      if (! xcf_seek_pos (info, offset, NULL))
 
221
        goto error;
 
222
 
 
223
      /* read in the layer */
 
224
      channel = xcf_load_channel (info, gimage);
 
225
      if (!channel)
 
226
        goto error;
 
227
 
 
228
      num_successful_elements++;
 
229
 
 
230
      /* add the channel to the image if its not the selection */
 
231
      if (channel != gimage->selection_mask)
 
232
        gimp_image_add_channel (gimage, channel, -1);
 
233
 
 
234
      /* restore the saved position so we'll be ready to
 
235
       *  read the next offset.
 
236
       */
 
237
      if (! xcf_seek_pos (info, saved_pos, NULL))
 
238
        goto error;
 
239
    }
 
240
 
 
241
  if (info->floating_sel && info->floating_sel_drawable)
 
242
    floating_sel_attach (info->floating_sel, info->floating_sel_drawable);
 
243
 
 
244
  if (info->active_layer)
 
245
    gimp_image_set_active_layer (gimage, info->active_layer);
 
246
 
 
247
  if (info->active_channel)
 
248
    gimp_image_set_active_channel (gimage, info->active_channel);
 
249
 
 
250
  gimp_image_set_filename (gimage, info->filename);
 
251
 
 
252
  if (info->tattoo_state > 0)
 
253
    gimp_image_set_tattoo_state (gimage, info->tattoo_state);
 
254
 
 
255
  return gimage;
 
256
 
 
257
 error:
 
258
  if (num_successful_elements == 0)
 
259
    goto hard_error;
 
260
 
 
261
  g_message ("XCF: This file is corrupt!  I have loaded as much\n"
 
262
             "of it as I can, but it is incomplete.");
 
263
 
 
264
  return gimage;
 
265
 
 
266
 hard_error:
 
267
  g_message ("XCF: This file is corrupt!  I could not even\n"
 
268
             "salvage any partial image data from it.");
 
269
 
 
270
  g_object_unref (gimage);
 
271
 
 
272
  return NULL;
 
273
}
 
274
 
 
275
static gboolean
 
276
xcf_load_image_props (XcfInfo   *info,
 
277
                      GimpImage *gimage)
 
278
{
 
279
  PropType prop_type;
 
280
  guint32  prop_size;
 
281
 
 
282
  while (TRUE)
 
283
    {
 
284
      if (!xcf_load_prop (info, &prop_type, &prop_size))
 
285
        return FALSE;
 
286
 
 
287
      switch (prop_type)
 
288
        {
 
289
        case PROP_END:
 
290
          return TRUE;
 
291
 
 
292
        case PROP_COLORMAP:
 
293
          if (info->file_version == 0)
 
294
            {
 
295
              gint i;
 
296
 
 
297
              g_message (_("XCF warning: version 0 of XCF file format\n"
 
298
                           "did not save indexed colormaps correctly.\n"
 
299
                           "Substituting grayscale map."));
 
300
              info->cp +=
 
301
                xcf_read_int32 (info->fp, (guint32 *) &gimage->num_cols, 1);
 
302
              gimage->cmap = g_new (guchar, gimage->num_cols * 3);
 
303
              if (!xcf_seek_pos (info, info->cp + gimage->num_cols, NULL))
 
304
                return FALSE;
 
305
 
 
306
              for (i = 0; i<gimage->num_cols; i++)
 
307
                {
 
308
                  gimage->cmap[i*3+0] = i;
 
309
                  gimage->cmap[i*3+1] = i;
 
310
                  gimage->cmap[i*3+2] = i;
 
311
                }
 
312
            }
 
313
          else
 
314
            {
 
315
              info->cp +=
 
316
                xcf_read_int32 (info->fp, (guint32 *) &gimage->num_cols, 1);
 
317
              gimage->cmap = g_new (guchar, gimage->num_cols * 3);
 
318
              info->cp +=
 
319
                xcf_read_int8 (info->fp,
 
320
                               (guint8 *) gimage->cmap, gimage->num_cols * 3);
 
321
            }
 
322
 
 
323
          /* discard color map, if image is not indexed, this is just
 
324
           * sanity checking to make sure gimp doesn't end up with an
 
325
           * image state that is impossible.
 
326
           */
 
327
          if (gimp_image_base_type (gimage) != GIMP_INDEXED)
 
328
            {
 
329
              g_free (gimage->cmap);
 
330
              gimage->cmap = NULL;
 
331
              gimage->num_cols = 0;
 
332
            }
 
333
          break;
 
334
 
 
335
        case PROP_COMPRESSION:
 
336
          {
 
337
            guint8 compression;
 
338
 
 
339
            info->cp += xcf_read_int8 (info->fp, (guint8 *) &compression, 1);
 
340
 
 
341
            if ((compression != COMPRESS_NONE) &&
 
342
                (compression != COMPRESS_RLE) &&
 
343
                (compression != COMPRESS_ZLIB) &&
 
344
                (compression != COMPRESS_FRACTAL))
 
345
              {
 
346
                g_message ("unknown compression type: %d", (int) compression);
 
347
                return FALSE;
 
348
              }
 
349
 
 
350
            info->compression = compression;
 
351
          }
 
352
          break;
 
353
 
 
354
        case PROP_GUIDES:
 
355
          {
 
356
            gint32 position;
 
357
            gint8  orientation;
 
358
            gint   i, nguides;
 
359
 
 
360
            nguides = prop_size / (4 + 1);
 
361
            for (i = 0; i < nguides; i++)
 
362
              {
 
363
                info->cp += xcf_read_int32 (info->fp, (guint32 *) &position, 1);
 
364
                info->cp += xcf_read_int8 (info->fp, (guint8 *) &orientation, 1);
 
365
 
 
366
                /*  skip -1 guides from old XCFs  */
 
367
                if (position < 0)
 
368
                  continue;
 
369
 
 
370
                switch (orientation)
 
371
                  {
 
372
                  case XCF_ORIENTATION_HORIZONTAL:
 
373
                    gimp_image_add_hguide (gimage, position, FALSE);
 
374
                    break;
 
375
 
 
376
                  case XCF_ORIENTATION_VERTICAL:
 
377
                    gimp_image_add_vguide (gimage, position, FALSE);
 
378
                    break;
 
379
 
 
380
                  default:
 
381
                    g_message ("guide orientation out of range in XCF file");
 
382
                    continue;
 
383
                  }
 
384
              }
 
385
 
 
386
            /*  this is silly as the order of guides doesn't really matter,
 
387
             *  but it restores the list to it's original order, which
 
388
             *  cannot be wrong  --Mitch
 
389
             */
 
390
            gimage->guides = g_list_reverse (gimage->guides);
 
391
          }
 
392
          break;
 
393
 
 
394
        case PROP_RESOLUTION:
 
395
          {
 
396
            gfloat xres, yres;
 
397
 
 
398
            info->cp += xcf_read_float (info->fp, &xres, 1);
 
399
            info->cp += xcf_read_float (info->fp, &yres, 1);
 
400
            if (xres < GIMP_MIN_RESOLUTION || xres > GIMP_MAX_RESOLUTION ||
 
401
                yres < GIMP_MIN_RESOLUTION || yres > GIMP_MAX_RESOLUTION)
 
402
              {
 
403
                g_message ("Warning, resolution out of range in XCF file");
 
404
                xres = gimage->gimp->config->default_image->xresolution;
 
405
                yres = gimage->gimp->config->default_image->yresolution;
 
406
              }
 
407
            gimage->xresolution = xres;
 
408
            gimage->yresolution = yres;
 
409
          }
 
410
          break;
 
411
 
 
412
        case PROP_TATTOO:
 
413
          {
 
414
            info->cp += xcf_read_int32 (info->fp, &info->tattoo_state, 1);
 
415
          }
 
416
          break;
 
417
 
 
418
        case PROP_PARASITES:
 
419
          {
 
420
            glong         base = info->cp;
 
421
            GimpParasite *p;
 
422
 
 
423
            while (info->cp - base < prop_size)
 
424
              {
 
425
                p = xcf_load_parasite (info);
 
426
                gimp_image_parasite_attach (gimage, p);
 
427
                gimp_parasite_free (p);
 
428
              }
 
429
            if (info->cp - base != prop_size)
 
430
              g_message ("Error while loading an image's parasites");
 
431
          }
 
432
          break;
 
433
 
 
434
        case PROP_UNIT:
 
435
          {
 
436
            guint32 unit;
 
437
 
 
438
            info->cp += xcf_read_int32 (info->fp, &unit, 1);
 
439
 
 
440
            if ((unit <= GIMP_UNIT_PIXEL) ||
 
441
                (unit >= _gimp_unit_get_number_of_built_in_units (gimage->gimp)))
 
442
              {
 
443
                g_message ("Warning, unit out of range in XCF file, "
 
444
                           "falling back to inches");
 
445
                unit = GIMP_UNIT_INCH;
 
446
              }
 
447
 
 
448
            gimage->resolution_unit = unit;
 
449
          }
 
450
          break;
 
451
 
 
452
        case PROP_PATHS:
 
453
          xcf_load_old_paths (info, gimage);
 
454
          break;
 
455
 
 
456
        case PROP_USER_UNIT:
 
457
          {
 
458
            gchar    *unit_strings[5];
 
459
            float     factor;
 
460
            guint32   digits;
 
461
            GimpUnit  unit;
 
462
            gint      num_units;
 
463
            gint      i;
 
464
 
 
465
            info->cp += xcf_read_float (info->fp, &factor, 1);
 
466
            info->cp += xcf_read_int32 (info->fp, &digits, 1);
 
467
            info->cp += xcf_read_string (info->fp, unit_strings, 5);
 
468
 
 
469
            for (i = 0; i < 5; i++)
 
470
              if (unit_strings[i] == NULL)
 
471
                unit_strings[i] = g_strdup ("");
 
472
 
 
473
            num_units = _gimp_unit_get_number_of_units (gimage->gimp);
 
474
 
 
475
            for (unit = _gimp_unit_get_number_of_built_in_units (gimage->gimp);
 
476
                 unit < num_units; unit++)
 
477
              {
 
478
                /* if the factor and the identifier match some unit
 
479
                 * in unitrc, use the unitrc unit
 
480
                 */
 
481
                if ((ABS (_gimp_unit_get_factor (gimage->gimp,
 
482
                                                 unit) - factor) < 1e-5) &&
 
483
                    (strcmp (unit_strings[0],
 
484
                             _gimp_unit_get_identifier (gimage->gimp,
 
485
                                                        unit)) == 0))
 
486
                  {
 
487
                    break;
 
488
                  }
 
489
              }
 
490
 
 
491
            /* no match */
 
492
            if (unit == num_units)
 
493
              unit = _gimp_unit_new (gimage->gimp,
 
494
                                     unit_strings[0],
 
495
                                     factor,
 
496
                                     digits,
 
497
                                     unit_strings[1],
 
498
                                     unit_strings[2],
 
499
                                     unit_strings[3],
 
500
                                     unit_strings[4]);
 
501
 
 
502
            gimage->resolution_unit = unit;
 
503
 
 
504
            for (i = 0; i < 5; i++)
 
505
              g_free (unit_strings[i]);
 
506
          }
 
507
         break;
 
508
 
 
509
        case PROP_VECTORS:
 
510
          {
 
511
            guint32 base = info->cp;
 
512
 
 
513
            if (xcf_load_vectors (info, gimage))
 
514
              {
 
515
                if (base + prop_size != info->cp)
 
516
                  {
 
517
                    g_warning ("Mismatch in PROP_VECTORS size: skipping %d bytes.",
 
518
                               base + prop_size - info->cp);
 
519
                    xcf_seek_pos (info, base + prop_size, NULL);
 
520
                  }
 
521
              }
 
522
            else
 
523
              {
 
524
                /* skip silently since we don't understand the format and
 
525
                 * xcf_load_vectors already explained what was wrong
 
526
                 */
 
527
                xcf_seek_pos (info, base + prop_size, NULL);
 
528
              }
 
529
          }
 
530
          break;
 
531
 
 
532
        default:
 
533
#ifdef GIMP_UNSTABLE
 
534
          g_printerr ("unexpected/unknown image property: %d (skipping)",
 
535
                      prop_type);
 
536
#endif
 
537
          {
 
538
            guint8 buf[16];
 
539
            guint  amount;
 
540
 
 
541
            while (prop_size > 0)
 
542
              {
 
543
                amount = MIN (16, prop_size);
 
544
                info->cp += xcf_read_int8 (info->fp, buf, amount);
 
545
                prop_size -= MIN (16, amount);
 
546
              }
 
547
          }
 
548
          break;
 
549
        }
 
550
    }
 
551
 
 
552
  return FALSE;
 
553
}
 
554
 
 
555
static gboolean
 
556
xcf_load_layer_props (XcfInfo   *info,
 
557
                      GimpImage *gimage,
 
558
                      GimpLayer *layer,
 
559
                      gboolean  *apply_mask,
 
560
                      gboolean  *edit_mask,
 
561
                      gboolean  *show_mask,
 
562
                      guint32   *text_layer_flags)
 
563
{
 
564
  PropType prop_type;
 
565
  guint32  prop_size;
 
566
 
 
567
  while (TRUE)
 
568
    {
 
569
      if (!xcf_load_prop (info, &prop_type, &prop_size))
 
570
        return FALSE;
 
571
 
 
572
      switch (prop_type)
 
573
        {
 
574
        case PROP_END:
 
575
          return TRUE;
 
576
 
 
577
        case PROP_ACTIVE_LAYER:
 
578
          info->active_layer = layer;
 
579
          break;
 
580
 
 
581
        case PROP_FLOATING_SELECTION:
 
582
          info->floating_sel = layer;
 
583
          info->cp +=
 
584
            xcf_read_int32 (info->fp,
 
585
                            (guint32 *) &info->floating_sel_offset, 1);
 
586
          break;
 
587
 
 
588
        case PROP_OPACITY:
 
589
          {
 
590
            guint32 opacity;
 
591
 
 
592
            info->cp += xcf_read_int32 (info->fp, &opacity, 1);
 
593
            layer->opacity = CLAMP ((gdouble) opacity / 255.0,
 
594
                                    GIMP_OPACITY_TRANSPARENT,
 
595
                                    GIMP_OPACITY_OPAQUE);
 
596
          }
 
597
          break;
 
598
 
 
599
        case PROP_VISIBLE:
 
600
          {
 
601
            gboolean visible;
 
602
 
 
603
            info->cp += xcf_read_int32 (info->fp, (guint32 *) &visible, 1);
 
604
            gimp_item_set_visible (GIMP_ITEM (layer),
 
605
                                   visible ? TRUE : FALSE, FALSE);
 
606
          }
 
607
          break;
 
608
 
 
609
        case PROP_LINKED:
 
610
          {
 
611
            gboolean linked;
 
612
 
 
613
            info->cp += xcf_read_int32 (info->fp, (guint32 *) &linked, 1);
 
614
            gimp_item_set_linked (GIMP_ITEM (layer),
 
615
                                  linked ? TRUE : FALSE, FALSE);
 
616
          }
 
617
          break;
 
618
 
 
619
        case PROP_PRESERVE_TRANSPARENCY:
 
620
          info->cp +=
 
621
            xcf_read_int32 (info->fp, (guint32 *) &layer->preserve_trans, 1);
 
622
          break;
 
623
 
 
624
        case PROP_APPLY_MASK:
 
625
          info->cp += xcf_read_int32 (info->fp, (guint32 *) apply_mask, 1);
 
626
          break;
 
627
 
 
628
        case PROP_EDIT_MASK:
 
629
          info->cp += xcf_read_int32 (info->fp, (guint32 *) edit_mask, 1);
 
630
          break;
 
631
 
 
632
        case PROP_SHOW_MASK:
 
633
          info->cp += xcf_read_int32 (info->fp, (guint32 *) show_mask, 1);
 
634
          break;
 
635
 
 
636
        case PROP_OFFSETS:
 
637
          info->cp +=
 
638
            xcf_read_int32 (info->fp,
 
639
                            (guint32 *) &GIMP_ITEM (layer)->offset_x, 1);
 
640
          info->cp +=
 
641
            xcf_read_int32 (info->fp,
 
642
                            (guint32 *) &GIMP_ITEM (layer)->offset_y, 1);
 
643
          break;
 
644
 
 
645
        case PROP_MODE:
 
646
          info->cp += xcf_read_int32 (info->fp, (guint32 *) &layer->mode, 1);
 
647
          break;
 
648
 
 
649
        case PROP_TATTOO:
 
650
          info->cp += xcf_read_int32 (info->fp,
 
651
                                      (guint32 *) &GIMP_ITEM (layer)->tattoo,
 
652
                                      1);
 
653
          break;
 
654
 
 
655
        case PROP_PARASITES:
 
656
          {
 
657
            glong         base = info->cp;
 
658
            GimpParasite *p;
 
659
 
 
660
            while (info->cp - base < prop_size)
 
661
              {
 
662
                p = xcf_load_parasite (info);
 
663
                gimp_item_parasite_attach (GIMP_ITEM (layer), p);
 
664
                gimp_parasite_free (p);
 
665
              }
 
666
            if (info->cp - base != prop_size)
 
667
              g_message ("Error while loading a layer's parasites");
 
668
          }
 
669
          break;
 
670
 
 
671
        case PROP_TEXT_LAYER_FLAGS:
 
672
          info->cp += xcf_read_int32 (info->fp, text_layer_flags, 1);
 
673
          break;
 
674
 
 
675
        default:
 
676
          {
 
677
            guint8 buf[16];
 
678
            guint  amount;
 
679
 
 
680
#ifdef GIMP_UNSTABLE
 
681
            g_printerr ("unexpected/unknown layer property: %d (skipping)",
 
682
                        prop_type);
 
683
#endif
 
684
            while (prop_size > 0)
 
685
              {
 
686
                amount = MIN (16, prop_size);
 
687
                info->cp += xcf_read_int8 (info->fp, buf, amount);
 
688
                prop_size -= MIN (16, amount);
 
689
              }
 
690
          }
 
691
          break;
 
692
        }
 
693
    }
 
694
 
 
695
  return FALSE;
 
696
}
 
697
 
 
698
static gboolean
 
699
xcf_load_channel_props (XcfInfo      *info,
 
700
                        GimpImage    *gimage,
 
701
                        GimpChannel **channel)
 
702
{
 
703
  PropType prop_type;
 
704
  guint32  prop_size;
 
705
 
 
706
  while (TRUE)
 
707
    {
 
708
      if (!xcf_load_prop (info, &prop_type, &prop_size))
 
709
        return FALSE;
 
710
 
 
711
      switch (prop_type)
 
712
        {
 
713
        case PROP_END:
 
714
          return TRUE;
 
715
 
 
716
        case PROP_ACTIVE_CHANNEL:
 
717
          info->active_channel = *channel;
 
718
          break;
 
719
 
 
720
        case PROP_SELECTION:
 
721
          g_object_unref (gimage->selection_mask);
 
722
          gimage->selection_mask =
 
723
            gimp_selection_new (gimage,
 
724
                                gimp_item_width (GIMP_ITEM (*channel)),
 
725
                                gimp_item_height (GIMP_ITEM (*channel)));
 
726
          g_object_ref (gimage->selection_mask);
 
727
          gimp_item_sink (GIMP_ITEM (gimage->selection_mask));
 
728
 
 
729
          tile_manager_unref (GIMP_DRAWABLE (gimage->selection_mask)->tiles);
 
730
          GIMP_DRAWABLE (gimage->selection_mask)->tiles =
 
731
            GIMP_DRAWABLE (*channel)->tiles;
 
732
          GIMP_DRAWABLE (*channel)->tiles = NULL;
 
733
          g_object_unref (*channel);
 
734
          *channel = gimage->selection_mask;
 
735
          (*channel)->boundary_known = FALSE;
 
736
          (*channel)->bounds_known   = FALSE;
 
737
          break;
 
738
 
 
739
        case PROP_OPACITY:
 
740
          {
 
741
            guint32 opacity;
 
742
 
 
743
            info->cp += xcf_read_int32 (info->fp, &opacity, 1);
 
744
            (*channel)->color.a = opacity / 255.0;
 
745
          }
 
746
          break;
 
747
 
 
748
        case PROP_VISIBLE:
 
749
          {
 
750
            gboolean visible;
 
751
 
 
752
            info->cp += xcf_read_int32 (info->fp, (guint32 *) &visible, 1);
 
753
            gimp_item_set_visible (GIMP_ITEM (*channel),
 
754
                                   visible ? TRUE : FALSE, FALSE);
 
755
          }
 
756
          break;
 
757
 
 
758
        case PROP_LINKED:
 
759
          {
 
760
            gboolean linked;
 
761
 
 
762
            info->cp += xcf_read_int32 (info->fp, (guint32 *) &linked, 1);
 
763
            gimp_item_set_linked (GIMP_ITEM (*channel),
 
764
                                  linked ? TRUE : FALSE, FALSE);
 
765
          }
 
766
          break;
 
767
 
 
768
        case PROP_SHOW_MASKED:
 
769
          {
 
770
            gboolean show_masked;
 
771
 
 
772
            info->cp += xcf_read_int32 (info->fp, (guint32 *) &show_masked, 1);
 
773
            gimp_channel_set_show_masked (*channel, show_masked);
 
774
          }
 
775
          break;
 
776
 
 
777
        case PROP_COLOR:
 
778
          {
 
779
            guchar col[3];
 
780
 
 
781
            info->cp += xcf_read_int8 (info->fp, (guint8 *) col, 3);
 
782
 
 
783
            gimp_rgb_set_uchar (&(*channel)->color, col[0], col[1], col[2]);
 
784
          }
 
785
          break;
 
786
 
 
787
        case PROP_TATTOO:
 
788
          info->cp +=
 
789
            xcf_read_int32 (info->fp, &GIMP_ITEM (*channel)->tattoo, 1);
 
790
          break;
 
791
 
 
792
        case PROP_PARASITES:
 
793
          {
 
794
            glong         base = info->cp;
 
795
            GimpParasite *p;
 
796
 
 
797
            while ((info->cp - base) < prop_size)
 
798
              {
 
799
                p = xcf_load_parasite (info);
 
800
                gimp_item_parasite_attach (GIMP_ITEM (*channel), p);
 
801
                gimp_parasite_free (p);
 
802
              }
 
803
            if (info->cp - base != prop_size)
 
804
              g_message ("Error while loading a channel's parasites");
 
805
          }
 
806
          break;
 
807
 
 
808
        default:
 
809
#ifdef GIMP_UNSTABLE
 
810
          g_printerr ("unexpected/unknown channel property: %d (skipping)",
 
811
                      prop_type);
 
812
#endif
 
813
 
 
814
          {
 
815
            guint8 buf[16];
 
816
            guint amount;
 
817
 
 
818
            while (prop_size > 0)
 
819
              {
 
820
                amount = MIN (16, prop_size);
 
821
                info->cp += xcf_read_int8 (info->fp, buf, amount);
 
822
                prop_size -= MIN (16, amount);
 
823
              }
 
824
          }
 
825
          break;
 
826
        }
 
827
    }
 
828
 
 
829
  return FALSE;
 
830
}
 
831
 
 
832
static gboolean
 
833
xcf_load_prop (XcfInfo  *info,
 
834
               PropType *prop_type,
 
835
               guint32  *prop_size)
 
836
{
 
837
  info->cp += xcf_read_int32 (info->fp, (guint32 *) prop_type, 1);
 
838
  info->cp += xcf_read_int32 (info->fp, (guint32 *) prop_size, 1);
 
839
  return TRUE;
 
840
}
 
841
 
 
842
static GimpLayer *
 
843
xcf_load_layer (XcfInfo   *info,
 
844
                GimpImage *gimage)
 
845
{
 
846
  GimpLayer     *layer;
 
847
  GimpLayerMask *layer_mask;
 
848
  guint32        hierarchy_offset;
 
849
  guint32        layer_mask_offset;
 
850
  gboolean       apply_mask = TRUE;
 
851
  gboolean       edit_mask  = FALSE;
 
852
  gboolean       show_mask  = FALSE;
 
853
  gboolean       active;
 
854
  gboolean       floating;
 
855
  guint32        text_layer_flags = 0;
 
856
  gint           width;
 
857
  gint           height;
 
858
  gint           type;
 
859
  gboolean       is_fs_drawable;
 
860
  gchar         *name;
 
861
 
 
862
  /* check and see if this is the drawable the floating selection
 
863
   *  is attached to. if it is then we'll do the attachment in our caller.
 
864
   */
 
865
  is_fs_drawable = (info->cp == info->floating_sel_offset);
 
866
 
 
867
  /* read in the layer width, height, type and name */
 
868
  info->cp += xcf_read_int32 (info->fp, (guint32 *) &width, 1);
 
869
  info->cp += xcf_read_int32 (info->fp, (guint32 *) &height, 1);
 
870
  info->cp += xcf_read_int32 (info->fp, (guint32 *) &type, 1);
 
871
  info->cp += xcf_read_string (info->fp, &name, 1);
 
872
 
 
873
  /* create a new layer */
 
874
  layer = gimp_layer_new (gimage, width, height,
 
875
                          type, name, 255, GIMP_NORMAL_MODE);
 
876
  g_free (name);
 
877
  if (! layer)
 
878
    return NULL;
 
879
 
 
880
  /* read in the layer properties */
 
881
  if (! xcf_load_layer_props (info, gimage, layer,
 
882
                              &apply_mask, &edit_mask, &show_mask,
 
883
                              &text_layer_flags))
 
884
    goto error;
 
885
 
 
886
  /* call the evil text layer hack that might change our layer pointer */
 
887
  active   = (info->active_layer == layer);
 
888
  floating = (info->floating_sel == layer);
 
889
 
 
890
  if (gimp_text_layer_xcf_load_hack (&layer))
 
891
    {
 
892
      gimp_text_layer_set_xcf_flags (GIMP_TEXT_LAYER (layer),
 
893
                                     text_layer_flags);
 
894
 
 
895
      if (active)
 
896
        info->active_layer = layer;
 
897
      if (floating)
 
898
        info->floating_sel = layer;
 
899
    }
 
900
 
 
901
  /* read the hierarchy and layer mask offsets */
 
902
  info->cp += xcf_read_int32 (info->fp, &hierarchy_offset, 1);
 
903
  info->cp += xcf_read_int32 (info->fp, &layer_mask_offset, 1);
 
904
 
 
905
  /* read in the hierarchy */
 
906
  if (! xcf_seek_pos (info, hierarchy_offset, NULL))
 
907
    goto error;
 
908
 
 
909
  if (! xcf_load_hierarchy (info, GIMP_DRAWABLE (layer)->tiles))
 
910
    goto error;
 
911
 
 
912
  /* read in the layer mask */
 
913
  if (layer_mask_offset != 0)
 
914
    {
 
915
      if (! xcf_seek_pos (info, layer_mask_offset, NULL))
 
916
        goto error;
 
917
 
 
918
      layer_mask = xcf_load_layer_mask (info, gimage);
 
919
      if (! layer_mask)
 
920
        goto error;
 
921
 
 
922
      layer_mask->apply_mask = apply_mask;
 
923
      layer_mask->edit_mask  = edit_mask;
 
924
      layer_mask->show_mask  = show_mask;
 
925
 
 
926
      gimp_layer_add_mask (layer, layer_mask, FALSE);
 
927
    }
 
928
 
 
929
  /* attach the floating selection... */
 
930
  if (is_fs_drawable)
 
931
    info->floating_sel_drawable = GIMP_DRAWABLE (layer);
 
932
 
 
933
  return layer;
 
934
 
 
935
 error:
 
936
  g_object_unref (layer);
 
937
  return NULL;
 
938
}
 
939
 
 
940
static GimpChannel *
 
941
xcf_load_channel (XcfInfo   *info,
 
942
                  GimpImage *gimage)
 
943
{
 
944
  GimpChannel *channel;
 
945
  guint32      hierarchy_offset;
 
946
  gint         width;
 
947
  gint         height;
 
948
  gboolean     is_fs_drawable;
 
949
  gchar       *name;
 
950
  GimpRGB      color = { 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE };
 
951
 
 
952
  /* check and see if this is the drawable the floating selection
 
953
   *  is attached to. if it is then we'll do the attachment in our caller.
 
954
   */
 
955
  is_fs_drawable = (info->cp == info->floating_sel_offset);
 
956
 
 
957
  /* read in the layer width, height and name */
 
958
  info->cp += xcf_read_int32 (info->fp, (guint32 *) &width, 1);
 
959
  info->cp += xcf_read_int32 (info->fp, (guint32 *) &height, 1);
 
960
  info->cp += xcf_read_string (info->fp, &name, 1);
 
961
 
 
962
  /* create a new channel */
 
963
  channel = gimp_channel_new (gimage, width, height, name, &color);
 
964
  g_free (name);
 
965
  if (!channel)
 
966
    return NULL;
 
967
 
 
968
  /* read in the channel properties */
 
969
  if (!xcf_load_channel_props (info, gimage, &channel))
 
970
    goto error;
 
971
 
 
972
  /* read the hierarchy and layer mask offsets */
 
973
  info->cp += xcf_read_int32 (info->fp, &hierarchy_offset, 1);
 
974
 
 
975
  /* read in the hierarchy */
 
976
  if (!xcf_seek_pos (info, hierarchy_offset, NULL))
 
977
    goto error;
 
978
 
 
979
  if (!xcf_load_hierarchy (info, GIMP_DRAWABLE (channel)->tiles))
 
980
    goto error;
 
981
 
 
982
  if (is_fs_drawable)
 
983
    info->floating_sel_drawable = GIMP_DRAWABLE (channel);
 
984
 
 
985
  return channel;
 
986
 
 
987
 error:
 
988
  g_object_unref (channel);
 
989
  return NULL;
 
990
}
 
991
 
 
992
static GimpLayerMask *
 
993
xcf_load_layer_mask (XcfInfo   *info,
 
994
                     GimpImage *gimage)
 
995
{
 
996
  GimpLayerMask *layer_mask;
 
997
  GimpChannel   *channel;
 
998
  guint32        hierarchy_offset;
 
999
  gint           width;
 
1000
  gint           height;
 
1001
  gboolean       is_fs_drawable;
 
1002
  gchar         *name;
 
1003
  GimpRGB        color = { 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE };
 
1004
 
 
1005
  /* check and see if this is the drawable the floating selection
 
1006
   *  is attached to. if it is then we'll do the attachment in our caller.
 
1007
   */
 
1008
  is_fs_drawable = (info->cp == info->floating_sel_offset);
 
1009
 
 
1010
  /* read in the layer width, height and name */
 
1011
  info->cp += xcf_read_int32 (info->fp, (guint32 *) &width, 1);
 
1012
  info->cp += xcf_read_int32 (info->fp, (guint32 *) &height, 1);
 
1013
  info->cp += xcf_read_string (info->fp, &name, 1);
 
1014
 
 
1015
  /* create a new layer mask */
 
1016
  layer_mask = gimp_layer_mask_new (gimage, width, height, name, &color);
 
1017
  g_free (name);
 
1018
  if (!layer_mask)
 
1019
    return NULL;
 
1020
 
 
1021
  /* read in the layer_mask properties */
 
1022
  channel = GIMP_CHANNEL (layer_mask);
 
1023
  if (!xcf_load_channel_props (info, gimage, &channel))
 
1024
    goto error;
 
1025
 
 
1026
  /* read the hierarchy and layer mask offsets */
 
1027
  info->cp += xcf_read_int32 (info->fp, &hierarchy_offset, 1);
 
1028
 
 
1029
  /* read in the hierarchy */
 
1030
  if (! xcf_seek_pos (info, hierarchy_offset, NULL))
 
1031
    goto error;
 
1032
 
 
1033
  if (!xcf_load_hierarchy (info, GIMP_DRAWABLE (layer_mask)->tiles))
 
1034
    goto error;
 
1035
 
 
1036
  /* attach the floating selection... */
 
1037
  if (is_fs_drawable)
 
1038
    info->floating_sel_drawable = GIMP_DRAWABLE (layer_mask);
 
1039
 
 
1040
  return layer_mask;
 
1041
 
 
1042
 error:
 
1043
  g_object_unref (layer_mask);
 
1044
  return NULL;
 
1045
}
 
1046
 
 
1047
static gboolean
 
1048
xcf_load_hierarchy (XcfInfo     *info,
 
1049
                    TileManager *tiles)
 
1050
{
 
1051
  guint32 saved_pos;
 
1052
  guint32 offset;
 
1053
  guint32 junk;
 
1054
  gint    width;
 
1055
  gint    height;
 
1056
  gint    bpp;
 
1057
 
 
1058
  info->cp += xcf_read_int32 (info->fp, (guint32 *) &width, 1);
 
1059
  info->cp += xcf_read_int32 (info->fp, (guint32 *) &height, 1);
 
1060
  info->cp += xcf_read_int32 (info->fp, (guint32 *) &bpp, 1);
 
1061
 
 
1062
  /* make sure the values in the file correspond to the values
 
1063
   *  calculated when the TileManager was created.
 
1064
   */
 
1065
  if (width  != tile_manager_width (tiles)  ||
 
1066
      height != tile_manager_height (tiles) ||
 
1067
      bpp    != tile_manager_bpp (tiles))
 
1068
    return FALSE;
 
1069
 
 
1070
  /* load in the levels...we make sure that the number of levels
 
1071
   *  calculated when the TileManager was created is the same
 
1072
   *  as the number of levels found in the file.
 
1073
   */
 
1074
 
 
1075
  info->cp += xcf_read_int32 (info->fp, &offset, 1); /* top level */
 
1076
 
 
1077
  /* discard offsets for layers below first, if any.
 
1078
   */
 
1079
  do
 
1080
    {
 
1081
      info->cp += xcf_read_int32 (info->fp, &junk, 1);
 
1082
    }
 
1083
  while (junk != 0);
 
1084
 
 
1085
  /* save the current position as it is where the
 
1086
   *  next level offset is stored.
 
1087
   */
 
1088
  saved_pos = info->cp;
 
1089
 
 
1090
  /* seek to the level offset */
 
1091
  if (!xcf_seek_pos (info, offset, NULL))
 
1092
    return FALSE;
 
1093
 
 
1094
  /* read in the level */
 
1095
  if (!xcf_load_level (info, tiles))
 
1096
    return FALSE;
 
1097
 
 
1098
  /* restore the saved position so we'll be ready to
 
1099
   *  read the next offset.
 
1100
   */
 
1101
  if (!xcf_seek_pos (info, saved_pos, NULL))
 
1102
    return FALSE;
 
1103
 
 
1104
  return TRUE;
 
1105
}
 
1106
 
 
1107
 
 
1108
static gboolean
 
1109
xcf_load_level (XcfInfo     *info,
 
1110
                TileManager *tiles)
 
1111
{
 
1112
  guint32 saved_pos;
 
1113
  guint32 offset, offset2;
 
1114
  guint ntiles;
 
1115
  gint width;
 
1116
  gint height;
 
1117
  gint i;
 
1118
  gint fail;
 
1119
  Tile *previous;
 
1120
  Tile *tile;
 
1121
 
 
1122
  info->cp += xcf_read_int32 (info->fp, (guint32 *) &width, 1);
 
1123
  info->cp += xcf_read_int32 (info->fp, (guint32 *) &height, 1);
 
1124
 
 
1125
  if (width  != tile_manager_width  (tiles) ||
 
1126
      height != tile_manager_height (tiles))
 
1127
    return FALSE;
 
1128
 
 
1129
  /* read in the first tile offset.
 
1130
   *  if it is '0', then this tile level is empty
 
1131
   *  and we can simply return.
 
1132
   */
 
1133
  info->cp += xcf_read_int32 (info->fp, &offset, 1);
 
1134
  if (offset == 0)
 
1135
    return TRUE;
 
1136
 
 
1137
  /* Initialise the reference for the in-memory tile-compression
 
1138
   */
 
1139
  previous = NULL;
 
1140
 
 
1141
  ntiles = tiles->ntile_rows * tiles->ntile_cols;
 
1142
  for (i = 0; i < ntiles; i++)
 
1143
    {
 
1144
      fail = FALSE;
 
1145
 
 
1146
      if (offset == 0)
 
1147
        {
 
1148
          g_message ("not enough tiles found in level");
 
1149
          return FALSE;
 
1150
        }
 
1151
 
 
1152
      /* save the current position as it is where the
 
1153
       *  next tile offset is stored.
 
1154
       */
 
1155
      saved_pos = info->cp;
 
1156
 
 
1157
      /* read in the offset of the next tile so we can calculate the amount
 
1158
         of data needed for this tile*/
 
1159
      info->cp += xcf_read_int32 (info->fp, &offset2, 1);
 
1160
 
 
1161
      /* if the offset is 0 then we need to read in the maximum possible
 
1162
         allowing for negative compression */
 
1163
      if (offset2 == 0)
 
1164
        offset2 = offset + TILE_WIDTH * TILE_WIDTH * 4 * 1.5;
 
1165
                                        /* 1.5 is probably more
 
1166
                                           than we need to allow */
 
1167
 
 
1168
      /* seek to the tile offset */
 
1169
      if (! xcf_seek_pos (info, offset, NULL))
 
1170
        return FALSE;
 
1171
 
 
1172
      /* get the tile from the tile manager */
 
1173
      tile = tile_manager_get (tiles, i, TRUE, TRUE);
 
1174
 
 
1175
      /* read in the tile */
 
1176
      switch (info->compression)
 
1177
        {
 
1178
        case COMPRESS_NONE:
 
1179
          if (!xcf_load_tile (info, tile))
 
1180
            fail = TRUE;
 
1181
          break;
 
1182
        case COMPRESS_RLE:
 
1183
          if (!xcf_load_tile_rle (info, tile, offset2 - offset))
 
1184
            fail = TRUE;
 
1185
          break;
 
1186
        case COMPRESS_ZLIB:
 
1187
          g_error ("xcf: zlib compression unimplemented");
 
1188
          fail = TRUE;
 
1189
          break;
 
1190
        case COMPRESS_FRACTAL:
 
1191
          g_error ("xcf: fractal compression unimplemented");
 
1192
          fail = TRUE;
 
1193
          break;
 
1194
        }
 
1195
 
 
1196
      if (fail)
 
1197
        {
 
1198
          tile_release (tile, TRUE);
 
1199
          return FALSE;
 
1200
        }
 
1201
 
 
1202
      /* To potentially save memory, we compare the
 
1203
       *  newly-fetched tile against the last one, and
 
1204
       *  if they're the same we copy-on-write mirror one against
 
1205
       *  the other.
 
1206
       */
 
1207
      if (previous != NULL)
 
1208
        {
 
1209
          tile_lock (previous);
 
1210
          if (tile_ewidth (tile) == tile_ewidth (previous) &&
 
1211
              tile_eheight (tile) == tile_eheight (previous) &&
 
1212
              tile_bpp (tile) == tile_bpp (previous) &&
 
1213
              memcmp (tile_data_pointer (tile, 0, 0),
 
1214
                      tile_data_pointer (previous, 0, 0),
 
1215
                      tile_size (tile)) == 0)
 
1216
            tile_manager_map (tiles, i, previous);
 
1217
          tile_release (previous, FALSE);
 
1218
        }
 
1219
      tile_release (tile, TRUE);
 
1220
      previous = tile_manager_get (tiles, i, FALSE, FALSE);
 
1221
 
 
1222
      /* restore the saved position so we'll be ready to
 
1223
       *  read the next offset.
 
1224
       */
 
1225
      if (!xcf_seek_pos (info, saved_pos, NULL))
 
1226
        return FALSE;
 
1227
 
 
1228
      /* read in the offset of the next tile */
 
1229
      info->cp += xcf_read_int32 (info->fp, &offset, 1);
 
1230
    }
 
1231
 
 
1232
  if (offset != 0)
 
1233
    {
 
1234
      g_message ("encountered garbage after reading level: %d", offset);
 
1235
      return FALSE;
 
1236
    }
 
1237
 
 
1238
  return TRUE;
 
1239
}
 
1240
 
 
1241
static gboolean
 
1242
xcf_load_tile (XcfInfo *info,
 
1243
               Tile    *tile)
 
1244
{
 
1245
#ifdef SWAP_FROM_FILE
 
1246
 
 
1247
  if (!info->swap_num)
 
1248
    {
 
1249
      info->ref_count = g_new (int, 1);
 
1250
      info->swap_num = tile_swap_add (info->filename,
 
1251
                                      xcf_swap_func,
 
1252
                                      info->ref_count);
 
1253
    }
 
1254
 
 
1255
  tile->swap_num = info->swap_num;
 
1256
  tile->swap_offset = info->cp;
 
1257
  *info->ref_count += 1;
 
1258
 
 
1259
#else
 
1260
 
 
1261
  info->cp += xcf_read_int8 (info->fp, tile_data_pointer(tile, 0, 0),
 
1262
                             tile_size (tile));
 
1263
 
 
1264
#endif
 
1265
 
 
1266
  return TRUE;
 
1267
}
 
1268
 
 
1269
static gboolean
 
1270
xcf_load_tile_rle (XcfInfo *info,
 
1271
                   Tile    *tile,
 
1272
                   int     data_length)
 
1273
{
 
1274
  guchar *data;
 
1275
  guchar val;
 
1276
  gint size;
 
1277
  gint count;
 
1278
  gint length;
 
1279
  gint bpp;
 
1280
  gint i, j;
 
1281
  gint nmemb_read_successfully;
 
1282
  guchar *xcfdata, *xcfodata, *xcfdatalimit;
 
1283
 
 
1284
  data = tile_data_pointer (tile, 0, 0);
 
1285
  bpp = tile_bpp (tile);
 
1286
 
 
1287
  xcfdata = xcfodata = g_malloc (data_length);
 
1288
 
 
1289
  /* we have to use fread instead of xcf_read_* because we may be
 
1290
     reading past the end of the file here */
 
1291
  nmemb_read_successfully = fread ((gchar *) xcfdata, sizeof (gchar),
 
1292
                                   data_length, info->fp);
 
1293
  info->cp += nmemb_read_successfully;
 
1294
 
 
1295
  xcfdatalimit = &xcfodata[nmemb_read_successfully - 1];
 
1296
 
 
1297
  for (i = 0; i < bpp; i++)
 
1298
    {
 
1299
      data = (guchar *) tile_data_pointer (tile, 0, 0) + i;
 
1300
      size = tile_ewidth (tile) * tile_eheight (tile);
 
1301
      count = 0;
 
1302
 
 
1303
      while (size > 0)
 
1304
        {
 
1305
          if (xcfdata > xcfdatalimit)
 
1306
            {
 
1307
              goto bogus_rle;
 
1308
            }
 
1309
 
 
1310
          val = *xcfdata++;
 
1311
 
 
1312
          length = val;
 
1313
          if (length >= 128)
 
1314
            {
 
1315
              length = 255 - (length - 1);
 
1316
              if (length == 128)
 
1317
                {
 
1318
                  if (xcfdata >= xcfdatalimit)
 
1319
                    {
 
1320
                      goto bogus_rle;
 
1321
                    }
 
1322
 
 
1323
                  length = (*xcfdata << 8) + xcfdata[1];
 
1324
                  xcfdata += 2;
 
1325
                }
 
1326
 
 
1327
              count += length;
 
1328
              size -= length;
 
1329
 
 
1330
              if (size < 0)
 
1331
                {
 
1332
                  goto bogus_rle;
 
1333
                }
 
1334
 
 
1335
              if (&xcfdata[length-1] > xcfdatalimit)
 
1336
                {
 
1337
                  goto bogus_rle;
 
1338
                }
 
1339
 
 
1340
              while (length-- > 0)
 
1341
                {
 
1342
                  *data = *xcfdata++;
 
1343
                  data += bpp;
 
1344
                }
 
1345
            }
 
1346
          else
 
1347
            {
 
1348
              length += 1;
 
1349
              if (length == 128)
 
1350
                {
 
1351
                  if (xcfdata >= xcfdatalimit)
 
1352
                    {
 
1353
                      goto bogus_rle;
 
1354
                    }
 
1355
 
 
1356
                  length = (*xcfdata << 8) + xcfdata[1];
 
1357
                  xcfdata += 2;
 
1358
                }
 
1359
 
 
1360
              count += length;
 
1361
              size -= length;
 
1362
 
 
1363
              if (size < 0)
 
1364
                {
 
1365
                  goto bogus_rle;
 
1366
                }
 
1367
 
 
1368
              if (xcfdata > xcfdatalimit)
 
1369
                {
 
1370
                  goto bogus_rle;
 
1371
                }
 
1372
 
 
1373
              val = *xcfdata++;
 
1374
 
 
1375
              for (j = 0; j < length; j++)
 
1376
                {
 
1377
                  *data = val;
 
1378
                  data += bpp;
 
1379
                }
 
1380
            }
 
1381
        }
 
1382
    }
 
1383
  g_free (xcfodata);
 
1384
  return TRUE;
 
1385
 
 
1386
 bogus_rle:
 
1387
  if (xcfodata)
 
1388
    g_free (xcfodata);
 
1389
  return FALSE;
 
1390
}
 
1391
 
 
1392
static GimpParasite *
 
1393
xcf_load_parasite (XcfInfo *info)
 
1394
{
 
1395
  GimpParasite *p;
 
1396
 
 
1397
  p = g_new (GimpParasite, 1);
 
1398
  info->cp += xcf_read_string (info->fp, &p->name, 1);
 
1399
  info->cp += xcf_read_int32 (info->fp, &p->flags, 1);
 
1400
  info->cp += xcf_read_int32 (info->fp, &p->size, 1);
 
1401
  p->data = g_new (gchar, p->size);
 
1402
  info->cp += xcf_read_int8 (info->fp, p->data, p->size);
 
1403
 
 
1404
  return p;
 
1405
}
 
1406
 
 
1407
static gboolean
 
1408
xcf_load_old_paths (XcfInfo   *info,
 
1409
                    GimpImage *gimage)
 
1410
{
 
1411
  guint32      num_paths;
 
1412
  guint32      last_selected_row;
 
1413
  GimpVectors *active_vectors;
 
1414
 
 
1415
  info->cp += xcf_read_int32 (info->fp, &last_selected_row, 1);
 
1416
  info->cp += xcf_read_int32 (info->fp, &num_paths, 1);
 
1417
 
 
1418
  while (num_paths-- > 0)
 
1419
    xcf_load_old_path (info, gimage);
 
1420
 
 
1421
  active_vectors = (GimpVectors *)
 
1422
    gimp_container_get_child_by_index (gimage->vectors, last_selected_row);
 
1423
 
 
1424
  if (active_vectors)
 
1425
    gimp_image_set_active_vectors (gimage, active_vectors);
 
1426
 
 
1427
  return TRUE;
 
1428
}
 
1429
 
 
1430
static gboolean
 
1431
xcf_load_old_path (XcfInfo   *info,
 
1432
                   GimpImage *gimage)
 
1433
{
 
1434
  gchar                  *name;
 
1435
  guint32                 locked;
 
1436
  guint8                  state;
 
1437
  guint32                 closed;
 
1438
  guint32                 num_points;
 
1439
  guint32                 version; /* changed from num_paths */
 
1440
  GimpTattoo              tattoo = 0;
 
1441
  GimpVectors            *vectors;
 
1442
  GimpVectorsCompatPoint *points;
 
1443
  gint                    i;
 
1444
 
 
1445
  info->cp += xcf_read_string (info->fp, &name, 1);
 
1446
  info->cp += xcf_read_int32  (info->fp, &locked, 1);
 
1447
  info->cp += xcf_read_int8   (info->fp, &state, 1);
 
1448
  info->cp += xcf_read_int32  (info->fp, &closed, 1);
 
1449
  info->cp += xcf_read_int32  (info->fp, &num_points, 1);
 
1450
  info->cp += xcf_read_int32  (info->fp, &version, 1);
 
1451
 
 
1452
  if (version == 2)
 
1453
    {
 
1454
      guint32 dummy;
 
1455
 
 
1456
      /* Had extra type field and points are stored as doubles */
 
1457
      info->cp += xcf_read_int32 (info->fp, (guint32 *) &dummy, 1);
 
1458
    }
 
1459
  else if (version == 3)
 
1460
    {
 
1461
      guint32 dummy;
 
1462
 
 
1463
      /* Has extra tatto field */
 
1464
      info->cp += xcf_read_int32 (info->fp, (guint32 *) &dummy,  1);
 
1465
      info->cp += xcf_read_int32 (info->fp, (guint32 *) &tattoo, 1);
 
1466
    }
 
1467
  else if (version != 1)
 
1468
    {
 
1469
      g_warning ("Unknown path type. Possibly corrupt XCF file");
 
1470
 
 
1471
      return FALSE;
 
1472
    }
 
1473
 
 
1474
  /* skip empty compatibility paths */
 
1475
  if (num_points == 0)
 
1476
    return FALSE;
 
1477
 
 
1478
  points = g_new0 (GimpVectorsCompatPoint, num_points);
 
1479
 
 
1480
  for (i = 0; i < num_points; i++)
 
1481
    {
 
1482
      if (version == 1)
 
1483
        {
 
1484
          gint32 x;
 
1485
          gint32 y;
 
1486
 
 
1487
          info->cp += xcf_read_int32 (info->fp, &points[i].type, 1);
 
1488
          info->cp += xcf_read_int32 (info->fp, (guint32 *) &x,  1);
 
1489
          info->cp += xcf_read_int32 (info->fp, (guint32 *) &y,  1);
 
1490
 
 
1491
          points[i].x = x;
 
1492
          points[i].y = y;
 
1493
        }
 
1494
      else
 
1495
        {
 
1496
          gfloat x;
 
1497
          gfloat y;
 
1498
 
 
1499
          info->cp += xcf_read_int32 (info->fp, &points[i].type, 1);
 
1500
          info->cp += xcf_read_float (info->fp, &x,              1);
 
1501
          info->cp += xcf_read_float (info->fp, &y,              1);
 
1502
 
 
1503
          points[i].x = x;
 
1504
          points[i].y = y;
 
1505
        }
 
1506
    }
 
1507
 
 
1508
  vectors = gimp_vectors_compat_new (gimage, name, points, num_points, closed);
 
1509
 
 
1510
  g_free (name);
 
1511
  g_free (points);
 
1512
 
 
1513
  GIMP_ITEM (vectors)->linked = locked;
 
1514
 
 
1515
  if (tattoo)
 
1516
    GIMP_ITEM (vectors)->tattoo = tattoo;
 
1517
 
 
1518
  gimp_image_add_vectors (gimage, vectors,
 
1519
                          gimp_container_num_children (gimage->vectors));
 
1520
 
 
1521
  return TRUE;
 
1522
}
 
1523
 
 
1524
static gboolean
 
1525
xcf_load_vectors (XcfInfo   *info,
 
1526
                  GimpImage *gimage)
 
1527
{
 
1528
  guint32      version;
 
1529
  guint32      active_index;
 
1530
  guint32      num_paths;
 
1531
  GimpVectors *active_vectors;
 
1532
  guint32      base;
 
1533
 
 
1534
#ifdef GIMP_XCF_PATH_DEBUG
 
1535
  g_printerr ("xcf_load_vectors\n");
 
1536
#endif
 
1537
 
 
1538
  base = info->cp;
 
1539
 
 
1540
  info->cp += xcf_read_int32  (info->fp, &version, 1);
 
1541
 
 
1542
  if (version != 1)
 
1543
    {
 
1544
      g_message ("Unknown vectors version: %d (skipping)", version);
 
1545
      return FALSE;
 
1546
    }
 
1547
 
 
1548
  info->cp += xcf_read_int32 (info->fp, &active_index, 1);
 
1549
  info->cp += xcf_read_int32 (info->fp, &num_paths,    1);
 
1550
 
 
1551
#ifdef GIMP_XCF_PATH_DEBUG
 
1552
  g_printerr ("%d paths (active: %d)\n", num_paths, active_index);
 
1553
#endif
 
1554
 
 
1555
  while (num_paths-- > 0)
 
1556
    if (! xcf_load_vector (info, gimage))
 
1557
      return FALSE;
 
1558
 
 
1559
  active_vectors = (GimpVectors *)
 
1560
    gimp_container_get_child_by_index (gimage->vectors, active_index);
 
1561
 
 
1562
  if (active_vectors)
 
1563
    gimp_image_set_active_vectors (gimage, active_vectors);
 
1564
 
 
1565
#ifdef GIMP_XCF_PATH_DEBUG
 
1566
  g_printerr ("xcf_load_vectors: loaded %d bytes\n", info->cp - base);
 
1567
#endif
 
1568
  return TRUE;
 
1569
}
 
1570
 
 
1571
static gboolean
 
1572
xcf_load_vector (XcfInfo   *info,
 
1573
                 GimpImage *gimage)
 
1574
{
 
1575
  gchar       *name;
 
1576
  GimpTattoo   tattoo = 0;
 
1577
  guint32      visible;
 
1578
  guint32      linked;
 
1579
  guint32      num_parasites;
 
1580
  guint32      num_strokes;
 
1581
  GimpVectors *vectors;
 
1582
  gint         i;
 
1583
 
 
1584
#ifdef GIMP_XCF_PATH_DEBUG
 
1585
  g_printerr ("xcf_load_vector\n");
 
1586
#endif
 
1587
 
 
1588
  info->cp += xcf_read_string (info->fp, &name,          1);
 
1589
  info->cp += xcf_read_int32  (info->fp, &tattoo,        1);
 
1590
  info->cp += xcf_read_int32  (info->fp, &visible,       1);
 
1591
  info->cp += xcf_read_int32  (info->fp, &linked,        1);
 
1592
  info->cp += xcf_read_int32  (info->fp, &num_parasites, 1);
 
1593
  info->cp += xcf_read_int32  (info->fp, &num_strokes,   1);
 
1594
 
 
1595
#ifdef GIMP_XCF_PATH_DEBUG
 
1596
  g_printerr ("name: %s, tattoo: %d, visible: %d, linked: %d, num_parasites %d, "
 
1597
              "num_strokes %d\n",
 
1598
              name, tattoo, visible, linked, num_parasites, num_strokes);
 
1599
#endif
 
1600
 
 
1601
  vectors = gimp_vectors_new (gimage, name);
 
1602
 
 
1603
  GIMP_ITEM (vectors)->visible = visible ? TRUE : FALSE;
 
1604
  GIMP_ITEM (vectors)->linked  = linked  ? TRUE : FALSE;
 
1605
 
 
1606
  if (tattoo)
 
1607
    GIMP_ITEM (vectors)->tattoo = tattoo;
 
1608
 
 
1609
  for (i = 0; i < num_parasites; i++)
 
1610
    {
 
1611
      GimpParasite *parasite;
 
1612
 
 
1613
      parasite = xcf_load_parasite (info);
 
1614
 
 
1615
      if (! parasite)
 
1616
        return FALSE;
 
1617
 
 
1618
      gimp_item_parasite_attach (GIMP_ITEM (vectors), parasite);
 
1619
      gimp_parasite_free (parasite);
 
1620
    }
 
1621
 
 
1622
  for (i = 0; i < num_strokes; i++)
 
1623
    {
 
1624
      gint         stroke_type_id;
 
1625
      gint         closed;
 
1626
      gint         num_axes;
 
1627
      gint         num_control_points;
 
1628
      gint         type;
 
1629
      gfloat       coords[6] = { 0.0, 0.0, 1.0, 0.5, 0.5, 0.5 };
 
1630
      GimpStroke  *stroke;
 
1631
      gint         j;
 
1632
 
 
1633
      GValueArray *control_points;
 
1634
      GValue       value = { 0, };
 
1635
      GimpAnchor   anchor;
 
1636
      GType        stroke_type;
 
1637
 
 
1638
      g_value_init (&value, GIMP_TYPE_ANCHOR);
 
1639
 
 
1640
      info->cp += xcf_read_int32 (info->fp, &stroke_type_id,     1);
 
1641
      info->cp += xcf_read_int32 (info->fp, &closed,             1);
 
1642
      info->cp += xcf_read_int32 (info->fp, &num_axes,           1);
 
1643
      info->cp += xcf_read_int32 (info->fp, &num_control_points, 1);
 
1644
 
 
1645
#ifdef GIMP_XCF_PATH_DEBUG
 
1646
      g_printerr ("stroke_type: %d, closed: %d, num_axes %d, len %d\n",
 
1647
                  stroke_type_id, closed, num_axes, num_control_points);
 
1648
#endif
 
1649
 
 
1650
      switch (stroke_type_id)
 
1651
        {
 
1652
        case XCF_STROKETYPE_BEZIER_STROKE:
 
1653
          stroke_type = GIMP_TYPE_BEZIER_STROKE;
 
1654
          break;
 
1655
 
 
1656
        default:
 
1657
          g_printerr ("skipping unknown stroke type\n");
 
1658
          xcf_seek_pos (info,
 
1659
                        info->cp + 4 * num_axes * num_control_points,
 
1660
                        NULL);
 
1661
          continue;
 
1662
        }
 
1663
 
 
1664
      control_points = g_value_array_new (num_control_points);
 
1665
 
 
1666
      anchor.selected = FALSE;
 
1667
 
 
1668
      for (j = 0; j < num_control_points; j++)
 
1669
        {
 
1670
          info->cp += xcf_read_int32 (info->fp, &type, 1);
 
1671
          info->cp += xcf_read_float (info->fp, coords, num_axes);
 
1672
 
 
1673
          anchor.type              = type;
 
1674
          anchor.position.x        = coords[0];
 
1675
          anchor.position.y        = coords[1];
 
1676
          anchor.position.pressure = coords[2];
 
1677
          anchor.position.xtilt    = coords[3];
 
1678
          anchor.position.ytilt    = coords[4];
 
1679
          anchor.position.wheel    = coords[5];
 
1680
 
 
1681
          g_value_set_boxed (&value, &anchor);
 
1682
          g_value_array_append (control_points, &value);
 
1683
 
 
1684
#ifdef GIMP_XCF_PATH_DEBUG
 
1685
          g_printerr ("Anchor: %d, (%f, %f, %f, %f, %f, %f)\n", type,
 
1686
                      coords[0], coords[1], coords[2], coords[3],
 
1687
                      coords[4], coords[5]);
 
1688
#endif
 
1689
        }
 
1690
 
 
1691
      g_value_unset (&value);
 
1692
 
 
1693
      stroke = g_object_new (stroke_type,
 
1694
                             "closed",         closed,
 
1695
                             "control-points", control_points,
 
1696
                             NULL);
 
1697
 
 
1698
      gimp_vectors_stroke_add (vectors, stroke);
 
1699
    }
 
1700
 
 
1701
  gimp_image_add_vectors (gimage, vectors,
 
1702
                          gimp_container_num_children (gimage->vectors));
 
1703
 
 
1704
  return TRUE;
 
1705
}
 
1706
 
 
1707
#ifdef SWAP_FROM_FILE
 
1708
 
 
1709
static gboolean
 
1710
xcf_swap_func (gint      fd,
 
1711
               Tile     *tile,
 
1712
               gint      cmd,
 
1713
               gpointer  user_data)
 
1714
{
 
1715
  gint bytes;
 
1716
  gint err;
 
1717
  gint nleft;
 
1718
  gint *ref_count;
 
1719
 
 
1720
  switch (cmd)
 
1721
    {
 
1722
    case SWAP_IN:
 
1723
      lseek (fd, tile->swap_offset, SEEK_SET);
 
1724
 
 
1725
      bytes = tile_size (tile);
 
1726
      tile_alloc (tile);
 
1727
 
 
1728
      nleft = bytes;
 
1729
      while (nleft > 0)
 
1730
        {
 
1731
          do {
 
1732
            err = read (fd, tile->data + bytes - nleft, nleft);
 
1733
          } while ((err == -1) && ((errno == EAGAIN) || (errno == EINTR)));
 
1734
 
 
1735
          if (err <= 0)
 
1736
            {
 
1737
              g_message ("unable to read tile data from xcf file: "
 
1738
                         "%d ( %d ) bytes read", err, nleft);
 
1739
              return FALSE;
 
1740
            }
 
1741
 
 
1742
          nleft -= err;
 
1743
        }
 
1744
      break;
 
1745
 
 
1746
    case SWAP_OUT:
 
1747
    case SWAP_DELETE:
 
1748
    case SWAP_COMPRESS:
 
1749
      ref_count = user_data;
 
1750
      *ref_count -= 1;
 
1751
      if (*ref_count == 0)
 
1752
        {
 
1753
          tile_swap_remove (tile->swap_num);
 
1754
          g_free (ref_count);
 
1755
        }
 
1756
 
 
1757
      tile->swap_num = 1;
 
1758
      tile->swap_offset = -1;
 
1759
 
 
1760
      return TRUE;
 
1761
    }
 
1762
 
 
1763
  return FALSE;
 
1764
}
 
1765
 
 
1766
#endif