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