00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "config.h"
00020
00021 #include <stdio.h>
00022 #include <string.h>
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 #include "xcf-private.h"
00062 #include "xcf-load.h"
00063 #include "xcf-read.h"
00064 #include "xcf-seek.h"
00065
00066
00067
00068 static bool xcf_load_image_props (XcfInfo * info, KisImage * gimage);
00069 static bool xcf_load_layer_props (XcfInfo * info,
00070 KisImage * gimage,
00071 KisLayer * layer,
00072 bool * apply_mask,
00073 bool * edit_mask,
00074 bool * show_mask,
00075 Q_INT32 * text_layer_flags);
00076 static bool xcf_load_channel_props (XcfInfo * info,
00077 KisImage * gimage,
00078 GimpChannel ** channel);
00079 static bool xcf_load_prop (XcfInfo * info,
00080 PropType * prop_type, Q_INT32 * prop_size);
00081 static KisLayer *xcf_load_layer (XcfInfo * info, KisImage * gimage);
00082
00083
00084
00085
00086 static bool xcf_load_hierarchy (XcfInfo * info, TileManager * tiles);
00087 static bool xcf_load_level (XcfInfo * info, TileManager * tiles);
00088 static bool xcf_load_tile (XcfInfo * info, Tile * tile);
00089 static bool xcf_load_tile_rle (XcfInfo * info,
00090 Tile * tile, Q_INT32 data_length);
00091
00092 static bool xcf_load_old_paths (XcfInfo * info, KisImage * gimage);
00093 static bool xcf_load_old_path (XcfInfo * info, KisImage * gimage);
00094 static bool xcf_load_vectors (XcfInfo * info, KisImage * gimage);
00095 static bool xcf_load_vector (XcfInfo * info, KisImage * gimage);
00096
00097 #ifdef SWAP_FROM_FILE
00098 static bool xcf_swap_func (Q_INT32 fd,
00099 Tile * tile, Q_INT32 cmd, gpointer user_data);
00100 #endif
00101
00102
00103 KisImage *
00104 xcf_load_image (XcfInfo * info)
00105 {
00106 KisImage *gimage;
00107 KisLayer *layer;
00108
00109
00110 Q_INT32 saved_pos;
00111 Q_INT32 offset;
00112 Q_INT32 width;
00113 Q_INT32 height;
00114 Q_INT32 image_type;
00115 Q_INT32 num_successful_elements = 0;
00116
00117
00118 info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) & width, 1);
00119 info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) & height, 1);
00120 info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) & image_type, 1);
00121
00122 gimage = gimp_create_image (gimp, width, height, image_type, FALSE);
00123
00124 gimp_image_undo_disable (gimage);
00125
00126
00127 if (!xcf_load_image_props (info, gimage))
00128 goto hard_error;
00129
00130
00131 parasite = gimp_image_parasite_find (GIMP_IMAGE (gimage),
00132 gimp_grid_parasite_name ());
00133 if (parasite)
00134 {
00135 GimpGrid *grid = gimp_grid_from_parasite (parasite);
00136
00137 if (grid)
00138 {
00139 gimp_parasite_list_remove (GIMP_IMAGE (gimage)->parasites,
00140 gimp_parasite_name (parasite));
00141
00142 gimp_image_set_grid (GIMP_IMAGE (gimage), grid, FALSE);
00143 }
00144 }
00145
00146 while (TRUE)
00147 {
00148
00149 info->cp += xcf_read_int32 (info->fp, &offset, 1);
00150
00151
00152
00153
00154 if (offset == 0)
00155 break;
00156
00157
00158
00159
00160 saved_pos = info->cp;
00161
00162
00163 if (!xcf_seek_pos (info, offset, NULL))
00164 goto error;
00165
00166
00167 layer = xcf_load_layer (info, gimage);
00168 if (!layer)
00169 goto error;
00170
00171 num_successful_elements++;
00172
00173
00174 if (layer != info->floating_sel)
00175 gimp_image_add_layer (gimage, layer,
00176 gimp_container_num_children (gimage->layers));
00177
00178
00179
00180
00181 if (!xcf_seek_pos (info, saved_pos, NULL))
00182 goto error;
00183 }
00184
00185 while (TRUE)
00186 {
00187
00188 info->cp += xcf_read_int32 (info->fp, &offset, 1);
00189
00190
00191
00192
00193 if (offset == 0)
00194 break;
00195
00196
00197
00198
00199 saved_pos = info->cp;
00200
00201
00202 if (!xcf_seek_pos (info, offset, NULL))
00203 goto error;
00204
00205
00206 channel = xcf_load_channel (info, gimage);
00207 if (!channel)
00208 goto error;
00209
00210 num_successful_elements++;
00211
00212
00213 if (channel != gimage->selection_mask)
00214 gimp_image_add_channel (gimage, channel, -1);
00215
00216
00217
00218
00219 if (!xcf_seek_pos (info, saved_pos, NULL))
00220 goto error;
00221 }
00222
00223 if (info->floating_sel && info->floating_sel_drawable)
00224 floating_sel_attach (info->floating_sel, info->floating_sel_drawable);
00225
00226 if (info->active_layer)
00227 gimp_image_set_active_layer (gimage, info->active_layer);
00228
00229 if (info->active_channel)
00230 gimp_image_set_active_channel (gimage, info->active_channel);
00231
00232 gimp_image_set_filename (gimage, info->filename);
00233
00234 if (info->tattoo_state > 0)
00235 gimp_image_set_tattoo_state (gimage, info->tattoo_state);
00236
00237 gimp_image_undo_enable (gimage);
00238
00239 return gimage;
00240
00241 error:
00242 if (num_successful_elements == 0)
00243 goto hard_error;
00244
00245 g_message ("XCF: This file is corrupt! I have loaded as much\n"
00246 "of it as I can, but it is incomplete.");
00247
00248 gimp_image_undo_enable (gimage);
00249
00250 return gimage;
00251
00252 hard_error:
00253 g_message ("XCF: This file is corrupt! I could not even\n"
00254 "salvage any partial image data from it.");
00255
00256 g_object_unref (gimage);
00257
00258 return NULL;
00259 }
00260
00261 static bool
00262 xcf_load_image_props (XcfInfo * info, KisImage * gimage)
00263 {
00264 PropType prop_type;
00265 Q_INT32 prop_size;
00266
00267 while (TRUE)
00268 {
00269 if (!xcf_load_prop (info, &prop_type, &prop_size))
00270 return FALSE;
00271
00272 switch (prop_type)
00273 {
00274 case PROP_END:
00275 return TRUE;
00276
00277 case PROP_COLORMAP:
00278 if (info->file_version == 0)
00279 {
00280 Q_INT32 i;
00281
00282 g_message (_("XCF warning: version 0 of XCF file format\n"
00283 "did not save indexed colormaps correctly.\n"
00284 "Substituting grayscale map."));
00285 info->cp +=
00286 xcf_read_int32 (info->fp, (Q_INT32 *) & gimage->num_cols, 1);
00287 gimage->cmap = g_new (guchar, gimage->num_cols * 3);
00288 if (!xcf_seek_pos (info, info->cp + gimage->num_cols, NULL))
00289 return FALSE;
00290
00291 for (i = 0; i < gimage->num_cols; i++)
00292 {
00293 gimage->cmap[i * 3 + 0] = i;
00294 gimage->cmap[i * 3 + 1] = i;
00295 gimage->cmap[i * 3 + 2] = i;
00296 }
00297 }
00298 else
00299 {
00300 info->cp +=
00301 xcf_read_int32 (info->fp, (Q_INT32 *) & gimage->num_cols, 1);
00302 gimage->cmap = g_new (guchar, gimage->num_cols * 3);
00303 info->cp +=
00304 xcf_read_int8 (info->fp,
00305 (Q_UINT8 *) gimage->cmap,
00306 gimage->num_cols * 3);
00307 }
00308
00309
00310
00311
00312
00313 if (gimp_image_base_type (gimage) != GIMP_INDEXED)
00314 {
00315 g_free (gimage->cmap);
00316 gimage->cmap = NULL;
00317 gimage->num_cols = 0;
00318 }
00319 break;
00320
00321 case PROP_COMPRESSION:
00322 {
00323 Q_UINT8 compression;
00324
00325 info->cp +=
00326 xcf_read_int8 (info->fp, (Q_UINT8 *) & compression, 1);
00327
00328 if ((compression != COMPRESS_NONE) &&
00329 (compression != COMPRESS_RLE) &&
00330 (compression != COMPRESS_ZLIB) &&
00331 (compression != COMPRESS_FRACTAL))
00332 {
00333 g_message ("unknown compression type: %d", (int) compression);
00334 return FALSE;
00335 }
00336
00337 info->compression = compression;
00338 }
00339 break;
00340
00341 case PROP_GUIDES:
00342 {
00343 Q_INT3232 position;
00344 Q_INT328 orientation;
00345 Q_INT32 i, nguides;
00346
00347 nguides = prop_size / (4 + 1);
00348 for (i = 0; i < nguides; i++)
00349 {
00350 info->cp +=
00351 xcf_read_int32 (info->fp, (Q_INT32 *) & position, 1);
00352 info->cp +=
00353 xcf_read_int8 (info->fp, (Q_UINT8 *) & orientation, 1);
00354
00355
00356 if (position < 0)
00357 continue;
00358
00359 switch (orientation)
00360 {
00361 case XCF_ORIENTATION_HORIZONTAL:
00362 gimp_image_add_hguide (gimage, position, FALSE);
00363 break;
00364
00365 case XCF_ORIENTATION_VERTICAL:
00366 gimp_image_add_vguide (gimage, position, FALSE);
00367 break;
00368
00369 default:
00370 g_message ("guide orientation out of range in XCF file");
00371 continue;
00372 }
00373 }
00374
00375
00376
00377
00378
00379 gimage->guides = g_list_reverse (gimage->guides);
00380 }
00381 break;
00382
00383 case PROP_RESOLUTION:
00384 {
00385 float xres, yres;
00386
00387 info->cp += xcf_read_float (info->fp, &xres, 1);
00388 info->cp += xcf_read_float (info->fp, &yres, 1);
00389 if (xres < GIMP_MIN_RESOLUTION || xres > GIMP_MAX_RESOLUTION ||
00390 yres < GIMP_MIN_RESOLUTION || yres > GIMP_MAX_RESOLUTION)
00391 {
00392 g_message ("Warning, resolution out of range in XCF file");
00393 xres = gimage->gimp->config->default_image->xresolution;
00394 yres = gimage->gimp->config->default_image->yresolution;
00395 }
00396 gimage->xresolution = xres;
00397 gimage->yresolution = yres;
00398 }
00399 break;
00400
00401 case PROP_TATTOO:
00402 {
00403 info->cp += xcf_read_int32 (info->fp, &info->tattoo_state, 1);
00404 }
00405 break;
00406
00407 case PROP_PARASITES:
00408 {
00409 glong base = info->cp;
00410 KisAnnotation *p;
00411
00412 while (info->cp - base < prop_size)
00413 {
00414 p = xcf_load_parasite (info);
00415 gimp_image_parasite_attach (gimage, p);
00416 gimp_parasite_free (p);
00417 }
00418 if (info->cp - base != prop_size)
00419 g_message ("Error while loading an image's parasites");
00420 }
00421 break;
00422
00423 case PROP_UNIT:
00424 {
00425 Q_INT32 unit;
00426
00427 info->cp += xcf_read_int32 (info->fp, &unit, 1);
00428
00429 if ((unit <= GIMP_UNIT_PIXEL) ||
00430 (unit >=
00431 _gimp_unit_get_number_of_built_in_units (gimage->gimp)))
00432 {
00433 g_message ("Warning, unit out of range in XCF file, "
00434 "falling back to inches");
00435 unit = GIMP_UNIT_INCH;
00436 }
00437
00438 gimage->resolution_unit = unit;
00439 }
00440 break;
00441
00442 case PROP_PATHS:
00443 xcf_load_old_paths (info, gimage);
00444 break;
00445
00446 case PROP_USER_UNIT:
00447 {
00448 QCString *unit_strings[5];
00449 float factor;
00450 Q_INT32 digits;
00451 GimpUnit unit;
00452 Q_INT32 num_units;
00453 Q_INT32 i;
00454
00455 info->cp += xcf_read_float (info->fp, &factor, 1);
00456 info->cp += xcf_read_int32 (info->fp, &digits, 1);
00457 info->cp += xcf_read_string (info->fp, unit_strings, 5);
00458
00459 for (i = 0; i < 5; i++)
00460 if (unit_strings[i] == NULL)
00461 unit_strings[i] = g_strdup ("");
00462
00463 num_units = _gimp_unit_get_number_of_units (gimage->gimp);
00464
00465 for (unit =
00466 _gimp_unit_get_number_of_built_in_units (gimage->gimp);
00467 unit < num_units; unit++)
00468 {
00469
00470
00471
00472 if ((ABS (_gimp_unit_get_factor (gimage->gimp,
00473 unit) - factor) < 1e-5) &&
00474 (strcmp (unit_strings[0],
00475 _gimp_unit_get_identifier (gimage->gimp,
00476 unit)) == 0))
00477 {
00478 break;
00479 }
00480 }
00481
00482
00483 if (unit == num_units)
00484 unit = _gimp_unit_new (gimage->gimp,
00485 unit_strings[0],
00486 factor,
00487 digits,
00488 unit_strings[1],
00489 unit_strings[2],
00490 unit_strings[3], unit_strings[4]);
00491
00492 gimage->resolution_unit = unit;
00493
00494 for (i = 0; i < 5; i++)
00495 g_free (unit_strings[i]);
00496 }
00497 break;
00498
00499 case PROP_VECTORS:
00500 {
00501 Q_INT32 base = info->cp;
00502
00503 if (xcf_load_vectors (info, gimage))
00504 {
00505 if (base + prop_size != info->cp)
00506 {
00507 g_warning
00508 ("Mismatch in PROP_VECTORS size: skipping %d bytes.",
00509 base + prop_size - info->cp);
00510 xcf_seek_pos (info, base + prop_size, NULL);
00511 }
00512 }
00513 else
00514 {
00515
00516
00517
00518 xcf_seek_pos (info, base + prop_size, NULL);
00519 }
00520 }
00521 break;
00522
00523 default:
00524 #ifdef GIMP_UNSTABLE
00525 g_printerr ("unexpected/unknown image property: %d (skipping)",
00526 prop_type);
00527 #endif
00528 {
00529 Q_UINT8 buf[16];
00530 Q_UINT32 amount;
00531
00532 while (prop_size > 0)
00533 {
00534 amount = MIN (16, prop_size);
00535 info->cp += xcf_read_int8 (info->fp, buf, amount);
00536 prop_size -= MIN (16, amount);
00537 }
00538 }
00539 break;
00540 }
00541 }
00542
00543 return FALSE;
00544 }
00545
00546 static bool
00547 xcf_load_layer_props (XcfInfo * info,
00548 KisImage * gimage,
00549 KisLayer * layer,
00550 bool * apply_mask,
00551 bool * edit_mask,
00552 bool * show_mask, Q_INT32 * text_layer_flags)
00553 {
00554 PropType prop_type;
00555 Q_INT32 prop_size;
00556
00557 while (TRUE)
00558 {
00559 if (!xcf_load_prop (info, &prop_type, &prop_size))
00560 return FALSE;
00561
00562 switch (prop_type)
00563 {
00564 case PROP_END:
00565 return TRUE;
00566
00567 case PROP_ACTIVE_LAYER:
00568 info->active_layer = layer;
00569 break;
00570
00571 case PROP_FLOATING_SELECTION:
00572 info->floating_sel = layer;
00573 info->cp +=
00574 xcf_read_int32 (info->fp,
00575 (Q_INT32 *) & info->floating_sel_offset, 1);
00576 break;
00577
00578 case PROP_OPACITY:
00579 {
00580 Q_INT32 opacity;
00581
00582 info->cp += xcf_read_int32 (info->fp, &opacity, 1);
00583 layer->opacity = CLAMP ((gdouble) opacity / 255.0,
00584 GIMP_OPACITY_TRANSPARENT,
00585 GIMP_OPACITY_OPAQUE);
00586 }
00587 break;
00588
00589 case PROP_VISIBLE:
00590 {
00591 bool visible;
00592
00593 info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) & visible, 1);
00594 gimp_item_set_visible (GIMP_ITEM (layer),
00595 visible ? TRUE : FALSE, FALSE);
00596 }
00597 break;
00598
00599 case PROP_LINKED:
00600 {
00601 bool linked;
00602
00603 info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) & linked, 1);
00604 gimp_item_set_linked (GIMP_ITEM (layer),
00605 linked ? TRUE : FALSE, FALSE);
00606 }
00607 break;
00608
00609 case PROP_LOCK_ALPHA:
00610 info->cp +=
00611 xcf_read_int32 (info->fp, (Q_INT32 *) & layer->lock_alpha, 1);
00612 break;
00613
00614 case PROP_APPLY_MASK:
00615 info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) apply_mask, 1);
00616 break;
00617
00618 case PROP_EDIT_MASK:
00619 info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) edit_mask, 1);
00620 break;
00621
00622 case PROP_SHOW_MASK:
00623 info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) show_mask, 1);
00624 break;
00625
00626 case PROP_OFFSETS:
00627 info->cp +=
00628 xcf_read_int32 (info->fp,
00629 (Q_INT32 *) & GIMP_ITEM (layer)->offset_x, 1);
00630 info->cp +=
00631 xcf_read_int32 (info->fp,
00632 (Q_INT32 *) & GIMP_ITEM (layer)->offset_y, 1);
00633 break;
00634
00635 case PROP_MODE:
00636 info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) & layer->mode, 1);
00637 break;
00638
00639 case PROP_TATTOO:
00640 info->cp += xcf_read_int32 (info->fp,
00641 (Q_INT32 *) & GIMP_ITEM (layer)->tattoo,
00642 1);
00643 break;
00644
00645 case PROP_PARASITES:
00646 {
00647 glong base = info->cp;
00648 KisAnnotation *p;
00649
00650 while (info->cp - base < prop_size)
00651 {
00652 p = xcf_load_parasite (info);
00653 gimp_item_parasite_attach (GIMP_ITEM (layer), p);
00654 gimp_parasite_free (p);
00655 }
00656 if (info->cp - base != prop_size)
00657 g_message ("Error while loading a layer's parasites");
00658 }
00659 break;
00660
00661 case PROP_TEXT_LAYER_FLAGS:
00662 info->cp += xcf_read_int32 (info->fp, text_layer_flags, 1);
00663 break;
00664
00665 default:
00666 {
00667 Q_UINT8 buf[16];
00668 Q_UINT32 amount;
00669
00670 #ifdef GIMP_UNSTABLE
00671 g_printerr ("unexpected/unknown layer property: %d (skipping)",
00672 prop_type);
00673 #endif
00674 while (prop_size > 0)
00675 {
00676 amount = MIN (16, prop_size);
00677 info->cp += xcf_read_int8 (info->fp, buf, amount);
00678 prop_size -= MIN (16, amount);
00679 }
00680 }
00681 break;
00682 }
00683 }
00684
00685 return FALSE;
00686 }
00687
00688 static bool
00689 xcf_load_channel_props (XcfInfo * info,
00690 KisImage * gimage, GimpChannel ** channel)
00691 {
00692 PropType prop_type;
00693 Q_INT32 prop_size;
00694
00695 while (TRUE)
00696 {
00697 if (!xcf_load_prop (info, &prop_type, &prop_size))
00698 return FALSE;
00699
00700 switch (prop_type)
00701 {
00702 case PROP_END:
00703 return TRUE;
00704
00705 case PROP_ACTIVE_CHANNEL:
00706 info->active_channel = *channel;
00707 break;
00708
00709 case PROP_SELECTION:
00710 g_object_unref (gimage->selection_mask);
00711 gimage->selection_mask =
00712 gimp_selection_new (gimage,
00713 gimp_item_width (GIMP_ITEM (*channel)),
00714 gimp_item_height (GIMP_ITEM (*channel)));
00715 g_object_ref (gimage->selection_mask);
00716 gimp_item_sink (GIMP_ITEM (gimage->selection_mask));
00717
00718 tile_manager_unref (GIMP_DRAWABLE (gimage->selection_mask)->tiles);
00719 GIMP_DRAWABLE (gimage->selection_mask)->tiles =
00720 GIMP_DRAWABLE (*channel)->tiles;
00721 GIMP_DRAWABLE (*channel)->tiles = NULL;
00722 g_object_unref (*channel);
00723 *channel = gimage->selection_mask;
00724 (*channel)->boundary_known = FALSE;
00725 (*channel)->bounds_known = FALSE;
00726 break;
00727
00728 case PROP_OPACITY:
00729 {
00730 Q_INT32 opacity;
00731
00732 info->cp += xcf_read_int32 (info->fp, &opacity, 1);
00733 (*channel)->color.a = opacity / 255.0;
00734 }
00735 break;
00736
00737 case PROP_VISIBLE:
00738 {
00739 bool visible;
00740
00741 info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) & visible, 1);
00742 gimp_item_set_visible (GIMP_ITEM (*channel),
00743 visible ? TRUE : FALSE, FALSE);
00744 }
00745 break;
00746
00747 case PROP_LINKED:
00748 {
00749 bool linked;
00750
00751 info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) & linked, 1);
00752 gimp_item_set_linked (GIMP_ITEM (*channel),
00753 linked ? TRUE : FALSE, FALSE);
00754 }
00755 break;
00756
00757 case PROP_SHOW_MASKED:
00758 {
00759 bool show_masked;
00760
00761 info->cp +=
00762 xcf_read_int32 (info->fp, (Q_INT32 *) & show_masked, 1);
00763 gimp_channel_set_show_masked (*channel, show_masked);
00764 }
00765 break;
00766
00767 case PROP_COLOR:
00768 {
00769 guchar col[3];
00770
00771 info->cp += xcf_read_int8 (info->fp, (Q_UINT8 *) col, 3);
00772
00773 gimp_rgb_set_uchar (&(*channel)->color, col[0], col[1], col[2]);
00774 }
00775 break;
00776
00777 case PROP_TATTOO:
00778 info->cp +=
00779 xcf_read_int32 (info->fp, &GIMP_ITEM (*channel)->tattoo, 1);
00780 break;
00781
00782 case PROP_PARASITES:
00783 {
00784 glong base = info->cp;
00785 KisAnnotation *p;
00786
00787 while ((info->cp - base) < prop_size)
00788 {
00789 p = xcf_load_parasite (info);
00790 gimp_item_parasite_attach (GIMP_ITEM (*channel), p);
00791 gimp_parasite_free (p);
00792 }
00793 if (info->cp - base != prop_size)
00794 g_message ("Error while loading a channel's parasites");
00795 }
00796 break;
00797
00798 default:
00799 #ifdef GIMP_UNSTABLE
00800 g_printerr ("unexpected/unknown channel property: %d (skipping)",
00801 prop_type);
00802 #endif
00803
00804 {
00805 Q_UINT8 buf[16];
00806 Q_UINT32 amount;
00807
00808 while (prop_size > 0)
00809 {
00810 amount = MIN (16, prop_size);
00811 info->cp += xcf_read_int8 (info->fp, buf, amount);
00812 prop_size -= MIN (16, amount);
00813 }
00814 }
00815 break;
00816 }
00817 }
00818
00819 return FALSE;
00820 }
00821
00822 static bool
00823 xcf_load_prop (XcfInfo * info, PropType * prop_type, Q_INT32 * prop_size)
00824 {
00825 info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) prop_type, 1);
00826 info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) prop_size, 1);
00827 return TRUE;
00828 }
00829
00830 static KisLayer *
00831 xcf_load_layer (XcfInfo * info, KisImage * gimage)
00832 {
00833 KisLayer *layer;
00834 GimpLayerMask *layer_mask;
00835 Q_INT32 hierarchy_offset;
00836 Q_INT32 layer_mask_offset;
00837 bool apply_mask = TRUE;
00838 bool edit_mask = FALSE;
00839 bool show_mask = FALSE;
00840 bool active;
00841 bool floating;
00842 Q_INT32 text_layer_flags = 0;
00843 Q_INT32 width;
00844 Q_INT32 height;
00845 Q_INT32 type;
00846 bool is_fs_drawable;
00847 QCString *name;
00848
00849
00850
00851
00852 is_fs_drawable = (info->cp == info->floating_sel_offset);
00853
00854
00855 info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) & width, 1);
00856 info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) & height, 1);
00857 info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) & type, 1);
00858 info->cp += xcf_read_string (info->fp, &name, 1);
00859
00860
00861 layer = gimp_layer_new (gimage, width, height,
00862 type, name, 255, GIMP_NORMAL_MODE);
00863 g_free (name);
00864 if (!layer)
00865 return NULL;
00866
00867
00868 if (!xcf_load_layer_props (info, gimage, layer,
00869 &apply_mask, &edit_mask, &show_mask,
00870 &text_layer_flags))
00871 goto error;
00872
00873
00874 active = (info->active_layer == layer);
00875 floating = (info->floating_sel == layer);
00876
00877 if (gimp_text_layer_xcf_load_hack (&layer))
00878 {
00879 gimp_text_layer_set_xcf_flags (GIMP_TEXT_LAYER (layer),
00880 text_layer_flags);
00881
00882 if (active)
00883 info->active_layer = layer;
00884 if (floating)
00885 info->floating_sel = layer;
00886 }
00887
00888
00889 info->cp += xcf_read_int32 (info->fp, &hierarchy_offset, 1);
00890 info->cp += xcf_read_int32 (info->fp, &layer_mask_offset, 1);
00891
00892
00893 if (!xcf_seek_pos (info, hierarchy_offset, NULL))
00894 goto error;
00895
00896 if (!xcf_load_hierarchy (info, GIMP_DRAWABLE (layer)->tiles))
00897 goto error;
00898
00899
00900 if (layer_mask_offset != 0)
00901 {
00902 if (!xcf_seek_pos (info, layer_mask_offset, NULL))
00903 goto error;
00904
00905 layer_mask = xcf_load_layer_mask (info, gimage);
00906 if (!layer_mask)
00907 goto error;
00908
00909 layer_mask->apply_mask = apply_mask;
00910 layer_mask->edit_mask = edit_mask;
00911 layer_mask->show_mask = show_mask;
00912
00913 gimp_layer_add_mask (layer, layer_mask, FALSE);
00914 }
00915
00916
00917 if (is_fs_drawable)
00918 info->floating_sel_drawable = GIMP_DRAWABLE (layer);
00919
00920 return layer;
00921
00922 error:
00923 g_object_unref (layer);
00924 return NULL;
00925 }
00926
00927 static GimpChannel *
00928 xcf_load_channel (XcfInfo * info, KisImage * gimage)
00929 {
00930 GimpChannel *channel;
00931 Q_INT32 hierarchy_offset;
00932 Q_INT32 width;
00933 Q_INT32 height;
00934 bool is_fs_drawable;
00935 QCString *name;
00936 GimpRGB color = { 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE };
00937
00938
00939
00940
00941 is_fs_drawable = (info->cp == info->floating_sel_offset);
00942
00943
00944 info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) & width, 1);
00945 info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) & height, 1);
00946 info->cp += xcf_read_string (info->fp, &name, 1);
00947
00948
00949 channel = gimp_channel_new (gimage, width, height, name, &color);
00950 g_free (name);
00951 if (!channel)
00952 return NULL;
00953
00954
00955 if (!xcf_load_channel_props (info, gimage, &channel))
00956 goto error;
00957
00958
00959 info->cp += xcf_read_int32 (info->fp, &hierarchy_offset, 1);
00960
00961
00962 if (!xcf_seek_pos (info, hierarchy_offset, NULL))
00963 goto error;
00964
00965 if (!xcf_load_hierarchy (info, GIMP_DRAWABLE (channel)->tiles))
00966 goto error;
00967
00968 if (is_fs_drawable)
00969 info->floating_sel_drawable = GIMP_DRAWABLE (channel);
00970
00971 return channel;
00972
00973 error:
00974 g_object_unref (channel);
00975 return NULL;
00976 }
00977
00978 static GimpLayerMask *
00979 xcf_load_layer_mask (XcfInfo * info, KisImage * gimage)
00980 {
00981 GimpLayerMask *layer_mask;
00982 GimpChannel *channel;
00983 Q_INT32 hierarchy_offset;
00984 Q_INT32 width;
00985 Q_INT32 height;
00986 bool is_fs_drawable;
00987 QCString *name;
00988 GimpRGB color = { 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE };
00989
00990
00991
00992
00993 is_fs_drawable = (info->cp == info->floating_sel_offset);
00994
00995
00996 info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) & width, 1);
00997 info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) & height, 1);
00998 info->cp += xcf_read_string (info->fp, &name, 1);
00999
01000
01001 layer_mask = gimp_layer_mask_new (gimage, width, height, name, &color);
01002 g_free (name);
01003 if (!layer_mask)
01004 return NULL;
01005
01006
01007 channel = GIMP_CHANNEL (layer_mask);
01008 if (!xcf_load_channel_props (info, gimage, &channel))
01009 goto error;
01010
01011
01012 info->cp += xcf_read_int32 (info->fp, &hierarchy_offset, 1);
01013
01014
01015 if (!xcf_seek_pos (info, hierarchy_offset, NULL))
01016 goto error;
01017
01018 if (!xcf_load_hierarchy (info, GIMP_DRAWABLE (layer_mask)->tiles))
01019 goto error;
01020
01021
01022 if (is_fs_drawable)
01023 info->floating_sel_drawable = GIMP_DRAWABLE (layer_mask);
01024
01025 return layer_mask;
01026
01027 error:
01028 g_object_unref (layer_mask);
01029 return NULL;
01030 }
01031
01032 static bool
01033 xcf_load_hierarchy (XcfInfo * info, TileManager * tiles)
01034 {
01035 Q_INT32 saved_pos;
01036 Q_INT32 offset;
01037 Q_INT32 junk;
01038 Q_INT32 width;
01039 Q_INT32 height;
01040 Q_INT32 bpp;
01041
01042 info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) & width, 1);
01043 info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) & height, 1);
01044 info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) & bpp, 1);
01045
01046
01047
01048
01049 if (width != tile_manager_width (tiles) ||
01050 height != tile_manager_height (tiles) ||
01051 bpp != tile_manager_bpp (tiles))
01052 return FALSE;
01053
01054
01055
01056
01057
01058
01059 info->cp += xcf_read_int32 (info->fp, &offset, 1);
01060
01061
01062
01063 do
01064 {
01065 info->cp += xcf_read_int32 (info->fp, &junk, 1);
01066 }
01067 while (junk != 0);
01068
01069
01070
01071
01072 saved_pos = info->cp;
01073
01074
01075 if (!xcf_seek_pos (info, offset, NULL))
01076 return FALSE;
01077
01078
01079 if (!xcf_load_level (info, tiles))
01080 return FALSE;
01081
01082
01083
01084
01085 if (!xcf_seek_pos (info, saved_pos, NULL))
01086 return FALSE;
01087
01088 return TRUE;
01089 }
01090
01091
01092 static bool
01093 xcf_load_level (XcfInfo * info, TileManager * tiles)
01094 {
01095 Q_INT32 saved_pos;
01096 Q_INT32 offset, offset2;
01097 Q_UINT32 ntiles;
01098 Q_INT32 width;
01099 Q_INT32 height;
01100 Q_INT32 i;
01101 Q_INT32 fail;
01102 Tile *previous;
01103 Tile *tile;
01104
01105 info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) & width, 1);
01106 info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) & height, 1);
01107
01108 if (width != tile_manager_width (tiles) ||
01109 height != tile_manager_height (tiles))
01110 return FALSE;
01111
01112
01113
01114
01115
01116 info->cp += xcf_read_int32 (info->fp, &offset, 1);
01117 if (offset == 0)
01118 return TRUE;
01119
01120
01121
01122 previous = NULL;
01123
01124 ntiles = tiles->ntile_rows * tiles->ntile_cols;
01125 for (i = 0; i < ntiles; i++)
01126 {
01127 fail = FALSE;
01128
01129 if (offset == 0)
01130 {
01131 g_message ("not enough tiles found in level");
01132 return FALSE;
01133 }
01134
01135
01136
01137
01138 saved_pos = info->cp;
01139
01140
01141
01142 info->cp += xcf_read_int32 (info->fp, &offset2, 1);
01143
01144
01145
01146 if (offset2 == 0)
01147 offset2 = offset + TILE_WIDTH * TILE_WIDTH * 4 * 1.5;
01148
01149
01150
01151
01152 if (!xcf_seek_pos (info, offset, NULL))
01153 return FALSE;
01154
01155
01156 tile = tile_manager_get (tiles, i, TRUE, TRUE);
01157
01158
01159 switch (info->compression)
01160 {
01161 case COMPRESS_NONE:
01162 if (!xcf_load_tile (info, tile))
01163 fail = TRUE;
01164 break;
01165 case COMPRESS_RLE:
01166 if (!xcf_load_tile_rle (info, tile, offset2 - offset))
01167 fail = TRUE;
01168 break;
01169 case COMPRESS_ZLIB:
01170 g_error ("xcf: zlib compression unimplemented");
01171 fail = TRUE;
01172 break;
01173 case COMPRESS_FRACTAL:
01174 g_error ("xcf: fractal compression unimplemented");
01175 fail = TRUE;
01176 break;
01177 }
01178
01179 if (fail)
01180 {
01181 tile_release (tile, TRUE);
01182 return FALSE;
01183 }
01184
01185
01186
01187
01188
01189
01190 if (previous != NULL)
01191 {
01192 tile_lock (previous);
01193 if (tile_ewidth (tile) == tile_ewidth (previous) &&
01194 tile_eheight (tile) == tile_eheight (previous) &&
01195 tile_bpp (tile) == tile_bpp (previous) &&
01196 memcmp (tile_data_pointer (tile, 0, 0),
01197 tile_data_pointer (previous, 0, 0),
01198 tile_size (tile)) == 0)
01199 tile_manager_map (tiles, i, previous);
01200 tile_release (previous, FALSE);
01201 }
01202 tile_release (tile, TRUE);
01203 previous = tile_manager_get (tiles, i, FALSE, FALSE);
01204
01205
01206
01207
01208 if (!xcf_seek_pos (info, saved_pos, NULL))
01209 return FALSE;
01210
01211
01212 info->cp += xcf_read_int32 (info->fp, &offset, 1);
01213 }
01214
01215 if (offset != 0)
01216 {
01217 g_message ("encountered garbage after reading level: %d", offset);
01218 return FALSE;
01219 }
01220
01221 return TRUE;
01222 }
01223
01224 static bool
01225 xcf_load_tile (XcfInfo * info, Tile * tile)
01226 {
01227 #ifdef SWAP_FROM_FILE
01228
01229 if (!info->swap_num)
01230 {
01231 info->ref_count = g_new (int, 1);
01232 info->swap_num = tile_swap_add (info->filename,
01233 xcf_swap_func, info->ref_count);
01234 }
01235
01236 tile->swap_num = info->swap_num;
01237 tile->swap_offset = info->cp;
01238 *info->ref_count += 1;
01239
01240 #else
01241
01242 info->cp += xcf_read_int8 (info->fp, tile_data_pointer (tile, 0, 0),
01243 tile_size (tile));
01244
01245 #endif
01246
01247 return TRUE;
01248 }
01249
01250 static bool
01251 xcf_load_tile_rle (XcfInfo * info, Tile * tile, int data_length)
01252 {
01253 guchar *data;
01254 guchar val;
01255 Q_INT32 size;
01256 Q_INT32 count;
01257 Q_INT32 length;
01258 Q_INT32 bpp;
01259 Q_INT32 i, j;
01260 Q_INT32 nmemb_read_successfully;
01261 guchar *xcfdata, *xcfodata, *xcfdatalimit;
01262
01263 data = tile_data_pointer (tile, 0, 0);
01264 bpp = tile_bpp (tile);
01265
01266 xcfdata = xcfodata = g_malloc (data_length);
01267
01268
01269
01270 nmemb_read_successfully = fread ((QCString *) xcfdata, sizeof (QCString),
01271 data_length, info->fp);
01272 info->cp += nmemb_read_successfully;
01273
01274 xcfdatalimit = &xcfodata[nmemb_read_successfully - 1];
01275
01276 for (i = 0; i < bpp; i++)
01277 {
01278 data = (guchar *) tile_data_pointer (tile, 0, 0) + i;
01279 size = tile_ewidth (tile) * tile_eheight (tile);
01280 count = 0;
01281
01282 while (size > 0)
01283 {
01284 if (xcfdata > xcfdatalimit)
01285 {
01286 goto bogus_rle;
01287 }
01288
01289 val = *xcfdata++;
01290
01291 length = val;
01292 if (length >= 128)
01293 {
01294 length = 255 - (length - 1);
01295 if (length == 128)
01296 {
01297 if (xcfdata >= xcfdatalimit)
01298 {
01299 goto bogus_rle;
01300 }
01301
01302 length = (*xcfdata << 8) + xcfdata[1];
01303 xcfdata += 2;
01304 }
01305
01306 count += length;
01307 size -= length;
01308
01309 if (size < 0)
01310 {
01311 goto bogus_rle;
01312 }
01313
01314 if (&xcfdata[length - 1] > xcfdatalimit)
01315 {
01316 goto bogus_rle;
01317 }
01318
01319 while (length-- > 0)
01320 {
01321 *data = *xcfdata++;
01322 data += bpp;
01323 }
01324 }
01325 else
01326 {
01327 length += 1;
01328 if (length == 128)
01329 {
01330 if (xcfdata >= xcfdatalimit)
01331 {
01332 goto bogus_rle;
01333 }
01334
01335 length = (*xcfdata << 8) + xcfdata[1];
01336 xcfdata += 2;
01337 }
01338
01339 count += length;
01340 size -= length;
01341
01342 if (size < 0)
01343 {
01344 goto bogus_rle;
01345 }
01346
01347 if (xcfdata > xcfdatalimit)
01348 {
01349 goto bogus_rle;
01350 }
01351
01352 val = *xcfdata++;
01353
01354 for (j = 0; j < length; j++)
01355 {
01356 *data = val;
01357 data += bpp;
01358 }
01359 }
01360 }
01361 }
01362 g_free (xcfodata);
01363 return TRUE;
01364
01365 bogus_rle:
01366 if (xcfodata)
01367 g_free (xcfodata);
01368 return FALSE;
01369 }
01370
01371 static KisAnnotation *
01372 xcf_load_parasite (XcfInfo * info)
01373 {
01374 KisAnnotation *p;
01375
01376 p = g_new (KisAnnotation, 1);
01377 info->cp += xcf_read_string (info->fp, &p->name, 1);
01378 info->cp += xcf_read_int32 (info->fp, &p->flags, 1);
01379 info->cp += xcf_read_int32 (info->fp, &p->size, 1);
01380 p->data = g_new (QCString, p->size);
01381 info->cp += xcf_read_int8 (info->fp, p->data, p->size);
01382
01383 return p;
01384 }
01385
01386 static bool
01387 xcf_load_old_paths (XcfInfo * info, KisImage * gimage)
01388 {
01389 Q_INT32 num_paths;
01390 Q_INT32 last_selected_row;
01391 GimpVectors *active_vectors;
01392
01393 info->cp += xcf_read_int32 (info->fp, &last_selected_row, 1);
01394 info->cp += xcf_read_int32 (info->fp, &num_paths, 1);
01395
01396 while (num_paths-- > 0)
01397 xcf_load_old_path (info, gimage);
01398
01399 active_vectors = (GimpVectors *)
01400 gimp_container_get_child_by_index (gimage->vectors, last_selected_row);
01401
01402 if (active_vectors)
01403 gimp_image_set_active_vectors (gimage, active_vectors);
01404
01405 return TRUE;
01406 }
01407
01408 static bool
01409 xcf_load_old_path (XcfInfo * info, KisImage * gimage)
01410 {
01411 QCString *name;
01412 Q_INT32 locked;
01413 Q_UINT8 state;
01414 Q_INT32 closed;
01415 Q_INT32 num_points;
01416 Q_INT32 version;
01417 GimpTattoo tattoo = 0;
01418 GimpVectors *vectors;
01419 GimpVectorsCompatPoint *points;
01420 Q_INT32 i;
01421
01422 info->cp += xcf_read_string (info->fp, &name, 1);
01423 info->cp += xcf_read_int32 (info->fp, &locked, 1);
01424 info->cp += xcf_read_int8 (info->fp, &state, 1);
01425 info->cp += xcf_read_int32 (info->fp, &closed, 1);
01426 info->cp += xcf_read_int32 (info->fp, &num_points, 1);
01427 info->cp += xcf_read_int32 (info->fp, &version, 1);
01428
01429 if (version == 2)
01430 {
01431 Q_INT32 dummy;
01432
01433
01434 info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) & dummy, 1);
01435 }
01436 else if (version == 3)
01437 {
01438 Q_INT32 dummy;
01439
01440
01441 info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) & dummy, 1);
01442 info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) & tattoo, 1);
01443 }
01444 else if (version != 1)
01445 {
01446 g_warning ("Unknown path type. Possibly corrupt XCF file");
01447
01448 return FALSE;
01449 }
01450
01451
01452 if (num_points == 0)
01453 return FALSE;
01454
01455 points = g_new0 (GimpVectorsCompatPoint, num_points);
01456
01457 for (i = 0; i < num_points; i++)
01458 {
01459 if (version == 1)
01460 {
01461 Q_INT3232 x;
01462 Q_INT3232 y;
01463
01464 info->cp += xcf_read_int32 (info->fp, &points[i].type, 1);
01465 info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) & x, 1);
01466 info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) & y, 1);
01467
01468 points[i].x = x;
01469 points[i].y = y;
01470 }
01471 else
01472 {
01473 float x;
01474 float y;
01475
01476 info->cp += xcf_read_int32 (info->fp, &points[i].type, 1);
01477 info->cp += xcf_read_float (info->fp, &x, 1);
01478 info->cp += xcf_read_float (info->fp, &y, 1);
01479
01480 points[i].x = x;
01481 points[i].y = y;
01482 }
01483 }
01484
01485 vectors =
01486 gimp_vectors_compat_new (gimage, name, points, num_points, closed);
01487
01488 g_free (name);
01489 g_free (points);
01490
01491 GIMP_ITEM (vectors)->linked = locked;
01492
01493 if (tattoo)
01494 GIMP_ITEM (vectors)->tattoo = tattoo;
01495
01496 gimp_image_add_vectors (gimage, vectors,
01497 gimp_container_num_children (gimage->vectors));
01498
01499 return TRUE;
01500 }
01501
01502 static bool
01503 xcf_load_vectors (XcfInfo * info, KisImage * gimage)
01504 {
01505 Q_INT32 version;
01506 Q_INT32 active_index;
01507 Q_INT32 num_paths;
01508 GimpVectors *active_vectors;
01509 Q_INT32 base;
01510
01511 #ifdef GIMP_XCF_PATH_DEBUG
01512 g_printerr ("xcf_load_vectors\n");
01513 #endif
01514
01515 base = info->cp;
01516
01517 info->cp += xcf_read_int32 (info->fp, &version, 1);
01518
01519 if (version != 1)
01520 {
01521 g_message ("Unknown vectors version: %d (skipping)", version);
01522 return FALSE;
01523 }
01524
01525 info->cp += xcf_read_int32 (info->fp, &active_index, 1);
01526 info->cp += xcf_read_int32 (info->fp, &num_paths, 1);
01527
01528 #ifdef GIMP_XCF_PATH_DEBUG
01529 g_printerr ("%d paths (active: %d)\n", num_paths, active_index);
01530 #endif
01531
01532 while (num_paths-- > 0)
01533 if (!xcf_load_vector (info, gimage))
01534 return FALSE;
01535
01536 active_vectors = (GimpVectors *)
01537 gimp_container_get_child_by_index (gimage->vectors, active_index);
01538
01539 if (active_vectors)
01540 gimp_image_set_active_vectors (gimage, active_vectors);
01541
01542 #ifdef GIMP_XCF_PATH_DEBUG
01543 g_printerr ("xcf_load_vectors: loaded %d bytes\n", info->cp - base);
01544 #endif
01545 return TRUE;
01546 }
01547
01548 static bool
01549 xcf_load_vector (XcfInfo * info, KisImage * gimage)
01550 {
01551 QCString *name;
01552 GimpTattoo tattoo = 0;
01553 Q_INT32 visible;
01554 Q_INT32 linked;
01555 Q_INT32 num_parasites;
01556 Q_INT32 num_strokes;
01557 GimpVectors *vectors;
01558 Q_INT32 i;
01559
01560 #ifdef GIMP_XCF_PATH_DEBUG
01561 g_printerr ("xcf_load_vector\n");
01562 #endif
01563
01564 info->cp += xcf_read_string (info->fp, &name, 1);
01565 info->cp += xcf_read_int32 (info->fp, &tattoo, 1);
01566 info->cp += xcf_read_int32 (info->fp, &visible, 1);
01567 info->cp += xcf_read_int32 (info->fp, &linked, 1);
01568 info->cp += xcf_read_int32 (info->fp, &num_parasites, 1);
01569 info->cp += xcf_read_int32 (info->fp, &num_strokes, 1);
01570
01571 #ifdef GIMP_XCF_PATH_DEBUG
01572 g_printerr
01573 ("name: %s, tattoo: %d, visible: %d, linked: %d, num_parasites %d, "
01574 "num_strokes %d\n", name, tattoo, visible, linked, num_parasites,
01575 num_strokes);
01576 #endif
01577
01578 vectors = gimp_vectors_new (gimage, name);
01579
01580 GIMP_ITEM (vectors)->visible = visible ? TRUE : FALSE;
01581 GIMP_ITEM (vectors)->linked = linked ? TRUE : FALSE;
01582
01583 if (tattoo)
01584 GIMP_ITEM (vectors)->tattoo = tattoo;
01585
01586 for (i = 0; i < num_parasites; i++)
01587 {
01588 KisAnnotation *parasite;
01589
01590 parasite = xcf_load_parasite (info);
01591
01592 if (!parasite)
01593 return FALSE;
01594
01595 gimp_item_parasite_attach (GIMP_ITEM (vectors), parasite);
01596 gimp_parasite_free (parasite);
01597 }
01598
01599 for (i = 0; i < num_strokes; i++)
01600 {
01601 Q_INT32 stroke_type_id;
01602 Q_INT32 closed;
01603 Q_INT32 num_axes;
01604 Q_INT32 num_control_points;
01605 Q_INT32 type;
01606 float coords[6] = { 0.0, 0.0, 1.0, 0.5, 0.5, 0.5 };
01607 GimpStroke *stroke;
01608 Q_INT32 j;
01609
01610 GValueArray *control_points;
01611 GValue value = { 0, };
01612 GimpAnchor anchor;
01613 GType stroke_type;
01614
01615 g_value_init (&value, GIMP_TYPE_ANCHOR);
01616
01617 info->cp += xcf_read_int32 (info->fp, &stroke_type_id, 1);
01618 info->cp += xcf_read_int32 (info->fp, &closed, 1);
01619 info->cp += xcf_read_int32 (info->fp, &num_axes, 1);
01620 info->cp += xcf_read_int32 (info->fp, &num_control_points, 1);
01621
01622 #ifdef GIMP_XCF_PATH_DEBUG
01623 g_printerr ("stroke_type: %d, closed: %d, num_axes %d, len %d\n",
01624 stroke_type_id, closed, num_axes, num_control_points);
01625 #endif
01626
01627 switch (stroke_type_id)
01628 {
01629 case XCF_STROKETYPE_BEZIER_STROKE:
01630 stroke_type = GIMP_TYPE_BEZIER_STROKE;
01631 break;
01632
01633 default:
01634 g_printerr ("skipping unknown stroke type\n");
01635 xcf_seek_pos (info,
01636 info->cp + 4 * num_axes * num_control_points, NULL);
01637 continue;
01638 }
01639
01640 control_points = g_value_array_new (num_control_points);
01641
01642 anchor.selected = FALSE;
01643
01644 for (j = 0; j < num_control_points; j++)
01645 {
01646 info->cp += xcf_read_int32 (info->fp, &type, 1);
01647 info->cp += xcf_read_float (info->fp, coords, num_axes);
01648
01649 anchor.type = type;
01650 anchor.position.x = coords[0];
01651 anchor.position.y = coords[1];
01652 anchor.position.pressure = coords[2];
01653 anchor.position.xtilt = coords[3];
01654 anchor.position.ytilt = coords[4];
01655 anchor.position.wheel = coords[5];
01656
01657 g_value_set_boxed (&value, &anchor);
01658 g_value_array_append (control_points, &value);
01659
01660 #ifdef GIMP_XCF_PATH_DEBUG
01661 g_printerr ("Anchor: %d, (%f, %f, %f, %f, %f, %f)\n", type,
01662 coords[0], coords[1], coords[2], coords[3],
01663 coords[4], coords[5]);
01664 #endif
01665 }
01666
01667 g_value_unset (&value);
01668
01669 stroke = g_object_new (stroke_type,
01670 "closed", closed,
01671 "control-points", control_points, NULL);
01672
01673 gimp_vectors_stroke_add (vectors, stroke);
01674 }
01675
01676 gimp_image_add_vectors (gimage, vectors,
01677 gimp_container_num_children (gimage->vectors));
01678
01679 return TRUE;
01680 }
01681
01682 #ifdef SWAP_FROM_FILE
01683
01684 static bool
01685 xcf_swap_func (Q_INT32 fd, Tile * tile, Q_INT32 cmd, gpointer user_data)
01686 {
01687 Q_INT32 bytes;
01688 Q_INT32 err;
01689 Q_INT32 nleft;
01690 Q_INT32 *ref_count;
01691
01692 switch (cmd)
01693 {
01694 case SWAP_IN:
01695 lseek (fd, tile->swap_offset, SEEK_SET);
01696
01697 bytes = tile_size (tile);
01698 tile_alloc (tile);
01699
01700 nleft = bytes;
01701 while (nleft > 0)
01702 {
01703 do
01704 {
01705 err = read (fd, tile->data + bytes - nleft, nleft);
01706 }
01707 while ((err == -1) && ((errno == EAGAIN) || (errno == EINTR)));
01708
01709 if (err <= 0)
01710 {
01711 g_message ("unable to read tile data from xcf file: "
01712 "%d ( %d ) bytes read", err, nleft);
01713 return FALSE;
01714 }
01715
01716 nleft -= err;
01717 }
01718 break;
01719
01720 case SWAP_OUT:
01721 case SWAP_DELETE:
01722 case SWAP_COMPRESS:
01723 ref_count = user_data;
01724 *ref_count -= 1;
01725 if (*ref_count == 0)
01726 {
01727 tile_swap_remove (tile->swap_num);
01728 g_free (ref_count);
01729 }
01730
01731 tile->swap_num = 1;
01732 tile->swap_offset = -1;
01733
01734 return TRUE;
01735 }
01736
01737 return FALSE;
01738 }
01739
01740 #endif