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 #include <glib-object.h>
00025
00026 #include "libgimpbase/gimpbase.h"
00027 #include "libgimpcolor/gimpcolor.h"
00028
00029 #include "core/core-types.h"
00030
00031 #include "base/tile.h"
00032 #include "base/tile-manager.h"
00033 #include "base/tile-manager-private.h"
00034
00035 #include "core/gimpchannel.h"
00036 #include "core/gimpdrawable.h"
00037 #include "core/gimpgrid.h"
00038 #include "core/gimpimage.h"
00039 #include "core/gimpimage-grid.h"
00040 #include "core/gimpimage-guides.h"
00041 #include "core/gimplayer.h"
00042 #include "core/gimplayer-floating-sel.h"
00043 #include "core/gimplayermask.h"
00044 #include "core/gimplist.h"
00045 #include "core/gimpparasitelist.h"
00046 #include "core/gimpunit.h"
00047
00048 #include "text/gimptextlayer.h"
00049 #include "text/gimptextlayer-xcf.h"
00050
00051 #include "vectors/gimpanchor.h"
00052 #include "vectors/gimpstroke.h"
00053 #include "vectors/gimpbezierstroke.h"
00054 #include "vectors/gimpvectors.h"
00055 #include "vectors/gimpvectors-compat.h"
00056
00057 #include "xcf-private.h"
00058 #include "xcf-read.h"
00059 #include "xcf-seek.h"
00060 #include "xcf-write.h"
00061
00062 #include "gimp-intl.h"
00063
00064
00065 static bool xcf_save_image_props (XcfInfo *info,
00066 KisImage *gimage,
00067 GError **error);
00068 static bool xcf_save_layer_props (XcfInfo *info,
00069 KisImage *gimage,
00070 KisLayer *layer,
00071 GError **error);
00072 static bool xcf_save_channel_props (XcfInfo *info,
00073 KisImage *gimage,
00074 GimpChannel *channel,
00075 GError **error);
00076 static bool xcf_save_prop (XcfInfo *info,
00077 KisImage *gimage,
00078 PropType prop_type,
00079 GError **error,
00080 ...);
00081 static bool xcf_save_layer (XcfInfo *info,
00082 KisImage *gimage,
00083 KisLayer *layer,
00084 GError **error);
00085 static bool xcf_save_channel (XcfInfo *info,
00086 KisImage *gimage,
00087 GimpChannel *channel,
00088 GError **error);
00089 static bool xcf_save_hierarchy (XcfInfo *info,
00090 TileManager *tiles,
00091 GError **error);
00092 static bool xcf_save_level (XcfInfo *info,
00093 TileManager *tiles,
00094 GError **error);
00095 static bool xcf_save_tile (XcfInfo *info,
00096 Tile *tile,
00097 GError **error);
00098 static bool xcf_save_tile_rle (XcfInfo *info,
00099 Tile *tile,
00100 guchar *rlebuf,
00101 GError **error);
00102 static bool xcf_save_parasite (XcfInfo *info,
00103 KisAnnotation *parasite,
00104 GError **error);
00105 static bool xcf_save_parasite_list (XcfInfo *info,
00106 KisAnnotationList *parasite,
00107 GError **error);
00108 static bool xcf_save_old_paths (XcfInfo *info,
00109 KisImage *gimage,
00110 GError **error);
00111 static bool xcf_save_vectors (XcfInfo *info,
00112 KisImage *gimage,
00113 GError **error);
00114
00115
00116
00117 #define xcf_write_int32_check_error(info, data, count) G_STMT_START { \
00118 info->cp += xcf_write_int32 (info->fp, data, count, &tmp_error); \
00119 if (tmp_error) \
00120 { \
00121 g_propagate_error (error, tmp_error); \
00122 return FALSE; \
00123 } \
00124 } G_STMT_END
00125
00126 #define xcf_write_int8_check_error(info, data, count) G_STMT_START { \
00127 info->cp += xcf_write_int8 (info->fp, data, count, &tmp_error); \
00128 if (tmp_error) \
00129 { \
00130 g_propagate_error (error, tmp_error); \
00131 return FALSE; \
00132 } \
00133 } G_STMT_END
00134
00135 #define xcf_write_float_check_error(info, data, count) G_STMT_START { \
00136 info->cp += xcf_write_float (info->fp, data, count, &tmp_error); \
00137 if (tmp_error) \
00138 { \
00139 g_propagate_error (error, tmp_error); \
00140 return FALSE; \
00141 } \
00142 } G_STMT_END
00143
00144 #define xcf_write_string_check_error(info, data, count) G_STMT_START { \
00145 info->cp += xcf_write_string (info->fp, data, count, &tmp_error); \
00146 if (tmp_error) \
00147 { \
00148 g_propagate_error (error, tmp_error); \
00149 return FALSE; \
00150 } \
00151 } G_STMT_END
00152
00153 #define xcf_write_int32_print_error(info, data, count) G_STMT_START { \
00154 info->cp += xcf_write_int32 (info->fp, data, count, &error); \
00155 if (error) \
00156 { \
00157 g_message (_("Error saving XCF file: %s"), \
00158 error->message); \
00159 return FALSE; \
00160 } \
00161 } G_STMT_END
00162
00163 #define xcf_write_int8_print_error(info, data, count) G_STMT_START { \
00164 info->cp += xcf_write_int8 (info->fp, data, count, &error); \
00165 if (error) \
00166 { \
00167 g_message (_("Error saving XCF file: %s"), \
00168 error->message); \
00169 return FALSE; \
00170 } \
00171 } G_STMT_END
00172
00173 #define xcf_write_float_print_error(info, data, count) G_STMT_START { \
00174 info->cp += xcf_write_float (info->fp, data, count, &error); \
00175 if (error) \
00176 { \
00177 g_message (_("Error saving XCF file: %s"), \
00178 error->message); \
00179 return FALSE; \
00180 } \
00181 } G_STMT_END
00182
00183 #define xcf_write_string_print_error(info, data, count) G_STMT_START { \
00184 info->cp += xcf_write_string (info->fp, data, count, &error); \
00185 if (error) \
00186 { \
00187 g_message (_("Error saving XCF file: %s"), \
00188 error->message); \
00189 return FALSE; \
00190 } \
00191 } G_STMT_END
00192
00193 #define xcf_write_prop_type_check_error(info, prop_type) G_STMT_START { \
00194 Q_INT32 _prop_int32 = prop_type; \
00195 xcf_write_int32_check_error (info, &_prop_int32, 1); \
00196 } G_STMT_END
00197
00198 #define xcf_write_prop_type_print_error(info, prop_type) G_STMT_START { \
00199 Q_INT32 _prop_int32 = prop_type; \
00200 xcf_write_int32_print_error (info, &_prop_int32, 1); \
00201 } G_STMT_END
00202
00203 #define xcf_check_error(x) G_STMT_START { \
00204 if (! (x)) \
00205 return FALSE; \
00206 } G_STMT_END
00207
00208 #define xcf_print_error(x) G_STMT_START { \
00209 if (! (x)) \
00210 { \
00211 g_message (_("Error saving XCF file: %s"), \
00212 error->message); \
00213 return FALSE; \
00214 } \
00215 } G_STMT_END
00216
00217
00218 void
00219 xcf_save_choose_format (XcfInfo *info,
00220 KisImage *gimage)
00221 {
00222 KisLayer *layer;
00223 GList *list;
00224
00225 Q_INT32 save_version = 0;
00226
00227 if (gimage->cmap)
00228 save_version = 1;
00229
00230 for (list = GIMP_LIST (gimage->layers)->list;
00231 list && save_version < 2;
00232 list = g_list_next (list))
00233 {
00234 layer = GIMP_LAYER (list->data);
00235
00236 switch (layer->mode)
00237 {
00238
00239 case GIMP_SOFTLIGHT_MODE:
00240 case GIMP_GRAIN_EXTRACT_MODE:
00241 case GIMP_GRAIN_MERGE_MODE:
00242 case GIMP_COLOR_ERASE_MODE:
00243 save_version = 2;
00244 break;
00245
00246 default:
00247 break;
00248 }
00249 }
00250
00251 info->file_version = save_version;
00252 }
00253
00254 Q_INT32
00255 xcf_save_image (XcfInfo *info,
00256 KisImage *gimage)
00257 {
00258 KisLayer *layer;
00259 KisLayer *floating_layer;
00260 GimpChannel *channel;
00261 Q_INT32 saved_pos;
00262 Q_INT32 offset;
00263 Q_UINT32 nlayers;
00264 Q_UINT32 nchannels;
00265 GList *list;
00266 bool have_selection;
00267 Q_INT32 t1, t2, t3, t4;
00268 QCString version_tag[14];
00269 GError *error = NULL;
00270
00271 floating_layer = gimp_image_floating_sel (gimage);
00272 if (floating_layer)
00273 floating_sel_relax (floating_layer, FALSE);
00274
00275
00276 if (info->file_version > 0)
00277 {
00278 sprintf (version_tag, "gimp xcf v%03d", info->file_version);
00279 }
00280 else
00281 {
00282 strcpy (version_tag, "gimp xcf file");
00283 }
00284 xcf_write_int8_print_error (info, (Q_UINT8 *) version_tag, 14);
00285
00286
00287 xcf_write_int32_print_error (info, (Q_INT32 *) &gimage->width, 1);
00288 xcf_write_int32_print_error (info, (Q_INT32 *) &gimage->height, 1);
00289 xcf_write_int32_print_error (info, (Q_INT32 *) &gimage->base_type, 1);
00290
00291
00292 nlayers = (Q_UINT32) gimp_container_num_children (gimage->layers);
00293 nchannels = (Q_UINT32) gimp_container_num_children (gimage->channels);
00294
00295
00296 have_selection = gimp_channel_bounds (gimp_image_get_mask (gimage),
00297 &t1, &t2, &t3, &t4);
00298 if (have_selection)
00299 nchannels += 1;
00300
00301
00302
00303
00304 xcf_print_error (xcf_save_image_props (info, gimage, &error));
00305
00306
00307
00308
00309 saved_pos = info->cp;
00310
00311
00312 xcf_print_error (xcf_seek_pos (info,
00313 info->cp + (nlayers + nchannels + 2) * 4,
00314 &error));
00315
00316 for (list = GIMP_LIST (gimage->layers)->list;
00317 list;
00318 list = g_list_next (list))
00319 {
00320 layer = (KisLayer *) list->data;
00321
00322
00323
00324
00325 offset = info->cp;
00326
00327
00328 xcf_print_error (xcf_save_layer (info, gimage, layer, &error));
00329
00330
00331
00332
00333 xcf_print_error (xcf_seek_pos (info, saved_pos, &error));
00334 xcf_write_int32_print_error (info, &offset, 1);
00335
00336
00337
00338
00339 saved_pos = info->cp;
00340
00341
00342
00343
00344 xcf_print_error (xcf_seek_end (info, &error));
00345 }
00346
00347
00348
00349
00350 offset = 0;
00351 xcf_print_error (xcf_seek_pos (info, saved_pos, &error));
00352 xcf_write_int32_print_error (info, &offset, 1);
00353 saved_pos = info->cp;
00354 xcf_print_error (xcf_seek_end (info, &error));
00355
00356 list = GIMP_LIST (gimage->channels)->list;
00357
00358 while (list || have_selection)
00359 {
00360 if (list)
00361 {
00362 channel = (GimpChannel *) list->data;
00363
00364 list = g_list_next (list);
00365 }
00366 else
00367 {
00368 channel = gimage->selection_mask;
00369 have_selection = FALSE;
00370 }
00371
00372
00373
00374
00375 offset = info->cp;
00376
00377
00378 xcf_print_error (xcf_save_channel (info, gimage, channel, &error));
00379
00380
00381
00382
00383 xcf_print_error (xcf_seek_pos (info, saved_pos, &error));
00384 xcf_write_int32_print_error (info, &offset, 1);
00385
00386
00387
00388
00389 saved_pos = info->cp;
00390
00391
00392
00393
00394 xcf_print_error (xcf_seek_end (info, &error));
00395 }
00396
00397
00398
00399
00400 offset = 0;
00401 xcf_print_error (xcf_seek_pos (info, saved_pos, &error));
00402 xcf_write_int32_print_error (info, &offset, 1);
00403 saved_pos = info->cp;
00404
00405 if (floating_layer)
00406 floating_sel_rigor (floating_layer, FALSE);
00407
00408 return !ferror(info->fp);
00409 }
00410
00411 static bool
00412 xcf_save_image_props (XcfInfo *info,
00413 KisImage *gimage,
00414 GError **error)
00415 {
00416 KisAnnotation *parasite = NULL;
00417 GimpUnit unit = gimp_image_get_unit (gimage);
00418
00419
00420 if (gimage->cmap)
00421 xcf_check_error (xcf_save_prop (info, gimage, PROP_COLORMAP, error,
00422 gimage->num_cols, gimage->cmap));
00423
00424 if (info->compression != COMPRESS_NONE)
00425 xcf_check_error (xcf_save_prop (info, gimage, PROP_COMPRESSION,
00426 error, info->compression));
00427
00428 if (gimage->guides)
00429 xcf_check_error (xcf_save_prop (info, gimage, PROP_GUIDES,
00430 error, gimage->guides));
00431
00432 xcf_check_error (xcf_save_prop (info, gimage, PROP_RESOLUTION, error,
00433 gimage->xresolution, gimage->yresolution));
00434
00435 xcf_check_error (xcf_save_prop (info, gimage, PROP_TATTOO, error,
00436 gimage->tattoo_state));
00437
00438 if (gimp_parasite_list_length (gimage->parasites) > 0)
00439 xcf_check_error (xcf_save_prop (info, gimage, PROP_PARASITES,
00440 error, gimage->parasites));
00441
00442 if (unit < _gimp_unit_get_number_of_built_in_units (gimage->gimp))
00443 xcf_check_error (xcf_save_prop (info, gimage, PROP_UNIT, error, unit));
00444
00445 if (gimp_container_num_children (gimage->vectors) > 0)
00446 {
00447 if (gimp_vectors_compat_is_compatible (gimage))
00448 xcf_check_error (xcf_save_prop (info, gimage, PROP_PATHS, error));
00449 else
00450 xcf_check_error (xcf_save_prop (info, gimage, PROP_VECTORS, error));
00451 }
00452
00453 if (unit >= _gimp_unit_get_number_of_built_in_units (gimage->gimp))
00454 xcf_check_error (xcf_save_prop (info, gimage, PROP_USER_UNIT, error, unit));
00455
00456 if (GIMP_IS_GRID (gimage->grid))
00457 {
00458 GimpGrid *grid = gimp_image_get_grid (gimage);
00459
00460 parasite = gimp_grid_to_parasite (grid);
00461 gimp_parasite_list_add (GIMP_IMAGE (gimage)->parasites, parasite);
00462 }
00463
00464 if (gimp_parasite_list_length (GIMP_IMAGE (gimage)->parasites) > 0)
00465 {
00466 xcf_check_error (xcf_save_prop (info, gimage, PROP_PARASITES, error,
00467 GIMP_IMAGE (gimage)->parasites));
00468 }
00469
00470 if (parasite)
00471 {
00472 gimp_parasite_list_remove (GIMP_IMAGE (gimage)->parasites,
00473 gimp_parasite_name (parasite));
00474 gimp_parasite_free (parasite);
00475 }
00476
00477 xcf_check_error (xcf_save_prop (info, gimage, PROP_END, error));
00478
00479 return TRUE;
00480 }
00481
00482 static bool
00483 xcf_save_layer_props (XcfInfo *info,
00484 KisImage *gimage,
00485 KisLayer *layer,
00486 GError **error)
00487 {
00488 KisAnnotation *parasite = NULL;
00489
00490 if (layer == gimp_image_get_active_layer (gimage))
00491 xcf_check_error (xcf_save_prop (info, gimage, PROP_ACTIVE_LAYER, error));
00492
00493 if (layer == gimp_image_floating_sel (gimage))
00494 {
00495 info->floating_sel_drawable = layer->fs.drawable;
00496 xcf_check_error (xcf_save_prop (info, gimage, PROP_FLOATING_SELECTION,
00497 error));
00498 }
00499
00500 xcf_check_error (xcf_save_prop (info, gimage, PROP_OPACITY, error,
00501 layer->opacity));
00502 xcf_check_error (xcf_save_prop (info, gimage, PROP_VISIBLE, error,
00503 gimp_item_get_visible (GIMP_ITEM (layer))));
00504 xcf_check_error (xcf_save_prop (info, gimage, PROP_LINKED, error,
00505 gimp_item_get_linked (GIMP_ITEM (layer))));
00506 xcf_check_error (xcf_save_prop (info, gimage, PROP_LOCK_ALPHA,
00507 error, layer->lock_alpha));
00508
00509 if (layer->mask)
00510 {
00511 xcf_check_error (xcf_save_prop (info, gimage, PROP_APPLY_MASK,
00512 error, layer->mask->apply_mask));
00513 xcf_check_error (xcf_save_prop (info, gimage, PROP_EDIT_MASK,
00514 error, layer->mask->edit_mask));
00515 xcf_check_error (xcf_save_prop (info, gimage, PROP_SHOW_MASK,
00516 error, layer->mask->show_mask));
00517 }
00518 else
00519 {
00520 xcf_check_error (xcf_save_prop (info, gimage, PROP_APPLY_MASK,
00521 error, FALSE));
00522 xcf_check_error (xcf_save_prop (info, gimage, PROP_EDIT_MASK,
00523 error, FALSE));
00524 xcf_check_error (xcf_save_prop (info, gimage, PROP_SHOW_MASK,
00525 error, FALSE));
00526 }
00527
00528 xcf_check_error (xcf_save_prop (info, gimage, PROP_OFFSETS, error,
00529 GIMP_ITEM (layer)->offset_x,
00530 GIMP_ITEM (layer)->offset_y));
00531 xcf_check_error (xcf_save_prop (info, gimage, PROP_MODE, error,
00532 layer->mode));
00533 xcf_check_error (xcf_save_prop (info, gimage, PROP_TATTOO, error,
00534 GIMP_ITEM (layer)->tattoo));
00535
00536 if (GIMP_IS_TEXT_LAYER (layer) && GIMP_TEXT_LAYER (layer)->text)
00537 {
00538 GimpTextLayer *text_layer = GIMP_TEXT_LAYER (layer);
00539 Q_INT32 flags = gimp_text_layer_get_xcf_flags (text_layer);
00540
00541 gimp_text_layer_xcf_save_prepare (text_layer);
00542
00543 if (flags)
00544 xcf_check_error (xcf_save_prop (info,
00545 gimage, PROP_TEXT_LAYER_FLAGS, error,
00546 flags));
00547 }
00548
00549 if (gimp_parasite_list_length (GIMP_ITEM (layer)->parasites) > 0)
00550 {
00551 xcf_check_error (xcf_save_prop (info, gimage, PROP_PARASITES, error,
00552 GIMP_ITEM (layer)->parasites));
00553 }
00554
00555 if (parasite)
00556 {
00557 gimp_parasite_list_remove (GIMP_ITEM (layer)->parasites,
00558 gimp_parasite_name (parasite));
00559 gimp_parasite_free (parasite);
00560 }
00561
00562 xcf_check_error (xcf_save_prop (info, gimage, PROP_END, error));
00563
00564 return TRUE;
00565 }
00566
00567 static bool
00568 xcf_save_channel_props (XcfInfo *info,
00569 KisImage *gimage,
00570 GimpChannel *channel,
00571 GError **error)
00572 {
00573 guchar col[3];
00574
00575 if (channel == gimp_image_get_active_channel (gimage))
00576 xcf_check_error (xcf_save_prop (info, gimage, PROP_ACTIVE_CHANNEL, error));
00577
00578 if (channel == gimage->selection_mask)
00579 xcf_check_error (xcf_save_prop (info, gimage, PROP_SELECTION, error));
00580
00581 xcf_check_error (xcf_save_prop (info, gimage, PROP_OPACITY, error,
00582 channel->color.a));
00583 xcf_check_error (xcf_save_prop (info, gimage, PROP_VISIBLE, error,
00584 gimp_item_get_visible (GIMP_ITEM (channel))));
00585 xcf_check_error (xcf_save_prop (info, gimage, PROP_LINKED, error,
00586 gimp_item_get_linked (GIMP_ITEM (channel))));
00587 xcf_check_error (xcf_save_prop (info, gimage, PROP_SHOW_MASKED, error,
00588 channel->show_masked));
00589
00590 gimp_rgb_get_uchar (&channel->color, &col[0], &col[1], &col[2]);
00591 xcf_check_error (xcf_save_prop (info, gimage, PROP_COLOR, error, col));
00592
00593 xcf_check_error (xcf_save_prop (info, gimage, PROP_TATTOO, error,
00594 GIMP_ITEM (channel)->tattoo));
00595
00596 if (gimp_parasite_list_length (GIMP_ITEM (channel)->parasites) > 0)
00597 xcf_check_error (xcf_save_prop (info, gimage, PROP_PARASITES, error,
00598 GIMP_ITEM (channel)->parasites));
00599
00600 xcf_check_error (xcf_save_prop (info, gimage, PROP_END, error));
00601
00602 return TRUE;
00603 }
00604
00605 static bool
00606 xcf_save_prop (XcfInfo *info,
00607 KisImage *gimage,
00608 PropType prop_type,
00609 GError **error,
00610 ...)
00611 {
00612 Q_INT32 size;
00613 va_list args;
00614
00615 GError *tmp_error = NULL;
00616
00617 va_start (args, error);
00618
00619 switch (prop_type)
00620 {
00621 case PROP_END:
00622 size = 0;
00623
00624 xcf_write_prop_type_check_error (info, prop_type);
00625 xcf_write_int32_check_error (info, &size, 1);
00626 break;
00627
00628 case PROP_COLORMAP:
00629 {
00630 Q_INT32 ncolors;
00631 guchar *colors;
00632
00633 ncolors = va_arg (args, Q_INT32);
00634 colors = va_arg (args, guchar*);
00635 size = 4 + ncolors * 3;
00636
00637 xcf_write_prop_type_check_error (info, prop_type);
00638 xcf_write_int32_check_error (info, &size, 1);
00639 xcf_write_int32_check_error (info, &ncolors, 1);
00640 xcf_write_int8_check_error (info, colors, ncolors * 3);
00641 }
00642 break;
00643
00644 case PROP_ACTIVE_LAYER:
00645 case PROP_ACTIVE_CHANNEL:
00646 case PROP_SELECTION:
00647 size = 0;
00648
00649 xcf_write_prop_type_check_error (info, prop_type);
00650 xcf_write_int32_check_error (info, &size, 1);
00651 break;
00652
00653 case PROP_FLOATING_SELECTION:
00654 {
00655 Q_INT32 dummy;
00656
00657 dummy = 0;
00658 size = 4;
00659
00660 xcf_write_prop_type_check_error (info, prop_type);
00661 xcf_write_int32_check_error (info, &size, 1);
00662 info->floating_sel_offset = info->cp;
00663 xcf_write_int32_check_error (info, &dummy, 1);
00664 }
00665 break;
00666
00667 case PROP_OPACITY:
00668 {
00669 gdouble opacity;
00670 Q_INT32 uint_opacity;
00671
00672 opacity = va_arg (args, gdouble);
00673
00674 uint_opacity = opacity * 255.999;
00675
00676 size = 4;
00677
00678 xcf_write_prop_type_check_error (info, prop_type);
00679 xcf_write_int32_check_error (info, &size, 1);
00680 xcf_write_int32_check_error (info, &uint_opacity, 1);
00681 }
00682 break;
00683
00684 case PROP_MODE:
00685 {
00686 Q_INT3232 mode;
00687
00688 mode = va_arg (args, Q_INT3232);
00689 size = 4;
00690
00691 xcf_write_prop_type_check_error (info, prop_type);
00692 xcf_write_int32_check_error (info, &size, 1);
00693 xcf_write_int32_check_error (info, (Q_INT32 *) &mode, 1);
00694 }
00695 break;
00696
00697 case PROP_VISIBLE:
00698 {
00699 Q_INT32 visible;
00700
00701 visible = va_arg (args, Q_INT32);
00702 size = 4;
00703
00704 xcf_write_prop_type_check_error (info, prop_type);
00705 xcf_write_int32_check_error (info, &size, 1);
00706 xcf_write_int32_check_error (info, &visible, 1);
00707 }
00708 break;
00709
00710 case PROP_LINKED:
00711 {
00712 Q_INT32 linked;
00713
00714 linked = va_arg (args, Q_INT32);
00715 size = 4;
00716
00717 xcf_write_prop_type_check_error (info, prop_type);
00718 xcf_write_int32_check_error (info, &size, 1);
00719 xcf_write_int32_check_error (info, &linked, 1);
00720 }
00721 break;
00722
00723 case PROP_LOCK_ALPHA:
00724 {
00725 Q_INT32 lock_alpha;
00726
00727 lock_alpha = va_arg (args, Q_INT32);
00728 size = 4;
00729
00730 xcf_write_prop_type_check_error (info, prop_type);
00731 xcf_write_int32_check_error (info, &size, 1);
00732 xcf_write_int32_check_error (info, &lock_alpha, 1);
00733 }
00734 break;
00735
00736 case PROP_APPLY_MASK:
00737 {
00738 Q_INT32 apply_mask;
00739
00740 apply_mask = va_arg (args, Q_INT32);
00741 size = 4;
00742
00743 xcf_write_prop_type_check_error (info, prop_type);
00744 xcf_write_int32_check_error (info, &size, 1);
00745 xcf_write_int32_check_error (info, &apply_mask, 1);
00746 }
00747 break;
00748
00749 case PROP_EDIT_MASK:
00750 {
00751 Q_INT32 edit_mask;
00752
00753 edit_mask = va_arg (args, Q_INT32);
00754 size = 4;
00755
00756 xcf_write_prop_type_check_error (info, prop_type);
00757 xcf_write_int32_check_error (info, &size, 1);
00758 xcf_write_int32_check_error (info, &edit_mask, 1);
00759 }
00760 break;
00761
00762 case PROP_SHOW_MASK:
00763 {
00764 Q_INT32 show_mask;
00765
00766 show_mask = va_arg (args, Q_INT32);
00767 size = 4;
00768
00769 xcf_write_prop_type_check_error (info, prop_type);
00770 xcf_write_int32_check_error (info, &size, 1);
00771 xcf_write_int32_check_error (info, &show_mask, 1);
00772 }
00773 break;
00774
00775 case PROP_SHOW_MASKED:
00776 {
00777 Q_INT32 show_masked;
00778
00779 show_masked = va_arg (args, Q_INT32);
00780 size = 4;
00781
00782 xcf_write_prop_type_check_error (info, prop_type);
00783 xcf_write_int32_check_error (info, &size, 1);
00784 xcf_write_int32_check_error (info, &show_masked, 1);
00785 }
00786 break;
00787
00788 case PROP_OFFSETS:
00789 {
00790 Q_INT3232 offsets[2];
00791
00792 offsets[0] = va_arg (args, Q_INT3232);
00793 offsets[1] = va_arg (args, Q_INT3232);
00794 size = 8;
00795
00796 xcf_write_prop_type_check_error (info, prop_type);
00797 xcf_write_int32_check_error (info, &size, 1);
00798 xcf_write_int32_check_error (info, (Q_INT32 *) offsets, 2);
00799 }
00800 break;
00801
00802 case PROP_COLOR:
00803 {
00804 guchar *color;
00805
00806 color = va_arg (args, guchar*);
00807 size = 3;
00808
00809 xcf_write_prop_type_check_error (info, prop_type);
00810 xcf_write_int32_check_error (info, &size, 1);
00811 xcf_write_int8_check_error (info, color, 3);
00812 }
00813 break;
00814
00815 case PROP_COMPRESSION:
00816 {
00817 Q_UINT8 compression;
00818
00819 compression = (Q_UINT8) va_arg (args, Q_INT32);
00820 size = 1;
00821
00822 xcf_write_prop_type_check_error (info, prop_type);
00823 xcf_write_int32_check_error (info, &size, 1);
00824 xcf_write_int8_check_error (info, &compression, 1);
00825 }
00826 break;
00827
00828 case PROP_GUIDES:
00829 {
00830 GList *guides;
00831 GimpGuide *guide;
00832 Q_INT3232 position;
00833 Q_INT328 orientation;
00834 Q_INT32 nguides;
00835
00836 guides = va_arg (args, GList *);
00837 nguides = g_list_length (guides);
00838
00839 size = nguides * (4 + 1);
00840
00841 xcf_write_prop_type_check_error (info, prop_type);
00842 xcf_write_int32_check_error (info, &size, 1);
00843
00844 for (; guides; guides = g_list_next (guides))
00845 {
00846 guide = (GimpGuide *) guides->data;
00847
00848 position = guide->position;
00849
00850 switch (guide->orientation)
00851 {
00852 case GIMP_ORIENTATION_HORIZONTAL:
00853 orientation = XCF_ORIENTATION_HORIZONTAL;
00854 break;
00855
00856 case GIMP_ORIENTATION_VERTICAL:
00857 orientation = XCF_ORIENTATION_VERTICAL;
00858 break;
00859
00860 default:
00861 g_warning ("%s: skipping guide with bad orientation",
00862 G_STRFUNC);
00863 continue;
00864 }
00865
00866 xcf_write_int32_check_error (info, (Q_INT32 *) &position, 1);
00867 xcf_write_int8_check_error (info, (Q_UINT8 *) &orientation, 1);
00868 }
00869 }
00870 break;
00871
00872 case PROP_RESOLUTION:
00873 {
00874 float xresolution, yresolution;
00875
00876
00877
00878 xresolution = va_arg (args, double);
00879 yresolution = va_arg (args, double);
00880
00881 size = 4*2;
00882
00883 xcf_write_prop_type_check_error (info, prop_type);
00884 xcf_write_int32_check_error (info, &size, 1);
00885
00886 xcf_write_float_check_error (info, &xresolution, 1);
00887 xcf_write_float_check_error (info, &yresolution, 1);
00888 }
00889 break;
00890
00891 case PROP_TATTOO:
00892 {
00893 Q_INT32 tattoo;
00894
00895 tattoo = va_arg (args, Q_INT32);
00896 size = 4;
00897
00898 xcf_write_prop_type_check_error (info, prop_type);
00899 xcf_write_int32_check_error (info, &size, 1);
00900 xcf_write_int32_check_error (info, &tattoo, 1);
00901 }
00902 break;
00903
00904 case PROP_PARASITES:
00905 {
00906 KisAnnotationList *list;
00907 Q_INT32 base, length;
00908 long pos;
00909
00910 list = va_arg (args, KisAnnotationList *);
00911
00912 if (gimp_parasite_list_persistent_length (list) > 0)
00913 {
00914 xcf_write_prop_type_check_error (info, prop_type);
00915
00916
00917
00918
00919 pos = info->cp;
00920 xcf_write_int32_check_error (info, &length, 1);
00921 base = info->cp;
00922
00923 xcf_check_error (xcf_save_parasite_list (info, list, error));
00924
00925 length = info->cp - base;
00926
00927 xcf_check_error (xcf_seek_pos (info, pos, error));
00928 xcf_write_int32 (info->fp, &length, 1, &tmp_error);
00929 if (tmp_error)
00930 {
00931 g_propagate_error (error, tmp_error);
00932 return FALSE;
00933 }
00934
00935 xcf_check_error (xcf_seek_end (info, error));
00936 }
00937 }
00938 break;
00939
00940 case PROP_UNIT:
00941 {
00942 Q_INT32 unit;
00943
00944 unit = va_arg (args, Q_INT32);
00945
00946 size = 4;
00947
00948 xcf_write_prop_type_check_error (info, prop_type);
00949 xcf_write_int32_check_error (info, &size, 1);
00950 xcf_write_int32_check_error (info, &unit, 1);
00951 }
00952 break;
00953
00954 case PROP_PATHS:
00955 {
00956 Q_INT32 base, length;
00957 glong pos;
00958
00959 xcf_write_prop_type_check_error (info, prop_type);
00960
00961
00962
00963
00964 pos = info->cp;
00965 xcf_write_int32_check_error (info, &length, 1);
00966
00967 base = info->cp;
00968
00969 xcf_check_error (xcf_save_old_paths (info, gimage, error));
00970
00971 length = info->cp - base;
00972
00973
00974 xcf_check_error (xcf_seek_pos (info, pos, error));
00975 xcf_write_int32 (info->fp, &length, 1, &tmp_error);
00976 if (tmp_error)
00977 {
00978 g_propagate_error (error, tmp_error);
00979 return FALSE;
00980 }
00981
00982 xcf_check_error (xcf_seek_end (info, error));
00983 }
00984 break;
00985
00986 case PROP_USER_UNIT:
00987 {
00988 GimpUnit unit;
00989 const QCString *unit_strings[5];
00990 float factor;
00991 Q_INT32 digits;
00992
00993 unit = va_arg (args, Q_INT32);
00994
00995
00996 unit_strings[0] = _gimp_unit_get_identifier (gimage->gimp, unit);
00997 factor = _gimp_unit_get_factor (gimage->gimp, unit);
00998 digits = _gimp_unit_get_digits (gimage->gimp, unit);
00999 unit_strings[1] = _gimp_unit_get_symbol (gimage->gimp, unit);
01000 unit_strings[2] = _gimp_unit_get_abbreviation (gimage->gimp, unit);
01001 unit_strings[3] = _gimp_unit_get_singular (gimage->gimp, unit);
01002 unit_strings[4] = _gimp_unit_get_plural (gimage->gimp, unit);
01003
01004 size =
01005 2 * 4 +
01006 strlen (unit_strings[0]) ? strlen (unit_strings[0]) + 5 : 4 +
01007 strlen (unit_strings[1]) ? strlen (unit_strings[1]) + 5 : 4 +
01008 strlen (unit_strings[2]) ? strlen (unit_strings[2]) + 5 : 4 +
01009 strlen (unit_strings[3]) ? strlen (unit_strings[3]) + 5 : 4 +
01010 strlen (unit_strings[4]) ? strlen (unit_strings[4]) + 5 : 4;
01011
01012 xcf_write_prop_type_check_error (info, prop_type);
01013 xcf_write_int32_check_error (info, &size, 1);
01014 xcf_write_float_check_error (info, &factor, 1);
01015 xcf_write_int32_check_error (info, &digits, 1);
01016 xcf_write_string_check_error (info, (QCString **) unit_strings, 5);
01017 }
01018 break;
01019
01020 case PROP_VECTORS:
01021 {
01022 Q_INT32 base, length;
01023 glong pos;
01024
01025 xcf_write_prop_type_check_error (info, prop_type);
01026
01027
01028
01029
01030 pos = info->cp;
01031 xcf_write_int32_check_error (info, &length, 1);
01032
01033 base = info->cp;
01034
01035 xcf_check_error (xcf_save_vectors (info, gimage, error));
01036
01037 length = info->cp - base;
01038
01039
01040 xcf_check_error (xcf_seek_pos (info, pos, error));
01041 xcf_write_int32 (info->fp, &length, 1, &tmp_error);
01042 if (tmp_error)
01043 {
01044 g_propagate_error (error, tmp_error);
01045 return FALSE;
01046 }
01047
01048 xcf_check_error (xcf_seek_end (info, error));
01049 }
01050 break;
01051
01052 case PROP_TEXT_LAYER_FLAGS:
01053 {
01054 Q_INT32 flags;
01055
01056 flags = va_arg (args, Q_INT32);
01057 size = 4;
01058
01059 xcf_write_prop_type_check_error (info, prop_type);
01060 xcf_write_int32_check_error (info, &size, 1);
01061 xcf_write_int32_check_error (info, &flags, 1);
01062 }
01063 break;
01064 }
01065
01066 va_end (args);
01067
01068 return TRUE;
01069 }
01070
01071 static bool
01072 xcf_save_layer (XcfInfo *info,
01073 KisImage *gimage,
01074 KisLayer *layer,
01075 GError **error)
01076 {
01077 Q_INT32 saved_pos;
01078 Q_INT32 offset;
01079
01080 GError *tmp_error = NULL;
01081
01082
01083
01084
01085 if (GIMP_DRAWABLE (layer) == info->floating_sel_drawable)
01086 {
01087 saved_pos = info->cp;
01088 xcf_check_error (xcf_seek_pos (info, info->floating_sel_offset, error));
01089 xcf_write_int32_check_error (info, &saved_pos, 1);
01090 xcf_check_error (xcf_seek_pos (info, saved_pos, error));
01091 }
01092
01093
01094 xcf_write_int32_check_error (info,
01095 (Q_INT32 *) &GIMP_ITEM (layer)->width, 1);
01096 xcf_write_int32_check_error (info,
01097 (Q_INT32 *) &GIMP_ITEM (layer)->height, 1);
01098 xcf_write_int32_check_error (info,
01099 (Q_INT32 *) &GIMP_DRAWABLE (layer)->type, 1);
01100
01101
01102 xcf_write_string_check_error (info, &GIMP_OBJECT (layer)->name, 1);
01103
01104
01105 xcf_save_layer_props (info, gimage, layer, error);
01106
01107
01108
01109
01110 saved_pos = info->cp;
01111
01112
01113 xcf_check_error (xcf_seek_pos (info, info->cp + 8, error));
01114 offset = info->cp;
01115
01116 xcf_check_error (xcf_save_hierarchy (info,
01117 GIMP_DRAWABLE(layer)->tiles, error));
01118
01119 xcf_check_error (xcf_seek_pos (info, saved_pos, error));
01120 xcf_write_int32_check_error (info, &offset, 1);
01121 saved_pos = info->cp;
01122
01123
01124 if (layer->mask)
01125 {
01126 xcf_check_error (xcf_seek_end (info, error));
01127 offset = info->cp;
01128
01129 xcf_check_error (xcf_save_channel (info,
01130 gimage, GIMP_CHANNEL(layer->mask),
01131 error));
01132 }
01133 else
01134 offset = 0;
01135
01136 xcf_check_error (xcf_seek_pos (info, saved_pos, error));
01137 xcf_write_int32_check_error (info, &offset, 1);
01138
01139 return TRUE;
01140 }
01141
01142 static bool
01143 xcf_save_channel (XcfInfo *info,
01144 KisImage *gimage,
01145 GimpChannel *channel,
01146 GError **error)
01147 {
01148 Q_INT32 saved_pos;
01149 Q_INT32 offset;
01150
01151 GError *tmp_error = NULL;
01152
01153
01154
01155
01156 if (GIMP_DRAWABLE (channel) == info->floating_sel_drawable)
01157 {
01158 saved_pos = info->cp;
01159 xcf_check_error (xcf_seek_pos (info, info->floating_sel_offset, error));
01160 xcf_write_int32_check_error (info, &saved_pos, 1);
01161 xcf_check_error (xcf_seek_pos (info, saved_pos, error));
01162 }
01163
01164
01165 xcf_write_int32_check_error (info,
01166 (Q_INT32 *) &GIMP_ITEM (channel)->width, 1);
01167 xcf_write_int32_check_error (info,
01168 (Q_INT32 *) &GIMP_ITEM (channel)->height, 1);
01169
01170
01171 xcf_write_string_check_error (info, &GIMP_OBJECT (channel)->name, 1);
01172
01173
01174 xcf_save_channel_props (info, gimage, channel, error);
01175
01176
01177
01178
01179 saved_pos = info->cp;
01180
01181
01182 xcf_check_error (xcf_seek_pos (info, info->cp + 4, error));
01183 offset = info->cp;
01184
01185 xcf_check_error (xcf_save_hierarchy (info,
01186 GIMP_DRAWABLE (channel)->tiles, error));
01187
01188 xcf_check_error (xcf_seek_pos (info, saved_pos, error));
01189 xcf_write_int32_check_error (info, &offset, 1);
01190 saved_pos = info->cp;
01191
01192 return TRUE;
01193 }
01194
01195 static Q_INT32
01196 xcf_calc_levels (Q_INT32 size,
01197 Q_INT32 tile_size)
01198 {
01199 int levels;
01200
01201 levels = 1;
01202 while (size > tile_size)
01203 {
01204 size /= 2;
01205 levels += 1;
01206 }
01207
01208 return levels;
01209 }
01210
01211
01212 static bool
01213 xcf_save_hierarchy (XcfInfo *info,
01214 TileManager *tiles,
01215 GError **error)
01216 {
01217 Q_INT32 saved_pos;
01218 Q_INT32 offset;
01219 Q_INT32 width;
01220 Q_INT32 height;
01221 Q_INT32 bpp;
01222 Q_INT32 i;
01223 Q_INT32 nlevels;
01224 Q_INT32 tmp1, tmp2;
01225
01226 GError *tmp_error = NULL;
01227
01228 width = tile_manager_width (tiles);
01229 height = tile_manager_height (tiles);
01230 bpp = tile_manager_bpp (tiles);
01231
01232 xcf_write_int32_check_error (info, (Q_INT32 *) &width, 1);
01233 xcf_write_int32_check_error (info, (Q_INT32 *) &height, 1);
01234 xcf_write_int32_check_error (info, (Q_INT32 *) &bpp, 1);
01235
01236 saved_pos = info->cp;
01237
01238 tmp1 = xcf_calc_levels (width, TILE_WIDTH);
01239 tmp2 = xcf_calc_levels (height, TILE_HEIGHT);
01240 nlevels = MAX (tmp1, tmp2);
01241
01242 xcf_check_error (xcf_seek_pos (info, info->cp + (1 + nlevels) * 4, error));
01243
01244 for (i = 0; i < nlevels; i++)
01245 {
01246 offset = info->cp;
01247
01248 if (i == 0)
01249 {
01250
01251 xcf_check_error (xcf_save_level (info, tiles, error));
01252 }
01253 else
01254 {
01255
01256 tmp1 = 0;
01257 width /= 2;
01258 height /= 2;
01259 xcf_write_int32_check_error (info, (Q_INT32 *) &width, 1);
01260 xcf_write_int32_check_error (info, (Q_INT32 *) &height, 1);
01261 xcf_write_int32_check_error (info, (Q_INT32 *) &tmp1, 1);
01262 }
01263
01264
01265
01266
01267 xcf_check_error (xcf_seek_pos (info, saved_pos, error));
01268 xcf_write_int32_check_error (info, &offset, 1);
01269
01270
01271
01272
01273 saved_pos = info->cp;
01274
01275
01276
01277
01278 xcf_check_error (xcf_seek_end (info, error));
01279 }
01280
01281
01282
01283
01284 offset = 0;
01285 xcf_check_error (xcf_seek_pos (info, saved_pos, error));
01286 xcf_write_int32_check_error (info, &offset, 1);
01287
01288 return TRUE;
01289 }
01290
01291 static bool
01292 xcf_save_level (XcfInfo *info,
01293 TileManager *level,
01294 GError **error)
01295 {
01296 Q_INT32 saved_pos;
01297 Q_INT32 offset;
01298 Q_INT32 width;
01299 Q_INT32 height;
01300 Q_UINT32 ntiles;
01301 Q_INT32 i;
01302 guchar *rlebuf;
01303
01304 GError *tmp_error = NULL;
01305
01306 width = tile_manager_width (level);
01307 height = tile_manager_height (level);
01308
01309 xcf_write_int32_check_error (info, (Q_INT32 *) &width, 1);
01310 xcf_write_int32_check_error (info, (Q_INT32 *) &height, 1);
01311
01312 saved_pos = info->cp;
01313
01314
01315
01316 rlebuf =
01317 g_malloc (TILE_WIDTH * TILE_HEIGHT * tile_manager_bpp (level) * 1.5);
01318
01319 if (level->tiles)
01320 {
01321 ntiles = level->ntile_rows * level->ntile_cols;
01322 xcf_check_error (xcf_seek_pos (info, info->cp + (ntiles + 1) * 4, error));
01323
01324 for (i = 0; i < ntiles; i++)
01325 {
01326
01327
01328
01329 offset = info->cp;
01330
01331
01332 switch (info->compression)
01333 {
01334 case COMPRESS_NONE:
01335 xcf_check_error(xcf_save_tile (info, level->tiles[i], error));
01336 break;
01337 case COMPRESS_RLE:
01338 xcf_check_error (xcf_save_tile_rle (info, level->tiles[i],
01339 rlebuf, error));
01340 break;
01341 case COMPRESS_ZLIB:
01342 g_error ("xcf: zlib compression unimplemented");
01343 break;
01344 case COMPRESS_FRACTAL:
01345 g_error ("xcf: fractal compression unimplemented");
01346 break;
01347 }
01348
01349
01350
01351
01352 xcf_check_error (xcf_seek_pos (info, saved_pos, error));
01353 xcf_write_int32_check_error (info, &offset, 1);
01354
01355
01356
01357
01358 saved_pos = info->cp;
01359
01360
01361
01362
01363 xcf_check_error (xcf_seek_end (info, error));
01364 }
01365 }
01366
01367 g_free (rlebuf);
01368
01369
01370
01371
01372 offset = 0;
01373 xcf_check_error (xcf_seek_pos (info, saved_pos, error));
01374 xcf_write_int32_check_error (info, &offset, 1);
01375
01376 return TRUE;
01377
01378 }
01379
01380 static bool
01381 xcf_save_tile (XcfInfo *info,
01382 Tile *tile,
01383 GError **error)
01384 {
01385 GError *tmp_error = NULL;
01386
01387 tile_lock (tile);
01388 xcf_write_int8_check_error (info, tile_data_pointer (tile, 0, 0),
01389 tile_size (tile));
01390 tile_release (tile, FALSE);
01391
01392 return TRUE;
01393 }
01394
01395 static bool
01396 xcf_save_tile_rle (XcfInfo *info,
01397 Tile *tile,
01398 guchar *rlebuf,
01399 GError **error)
01400 {
01401 guchar *data, *t;
01402 unsigned int last;
01403 Q_INT32 state;
01404 Q_INT32 length;
01405 Q_INT32 count;
01406 Q_INT32 size;
01407 Q_INT32 bpp;
01408 Q_INT32 i, j;
01409 Q_INT32 len = 0;
01410
01411 GError *tmp_error = NULL;
01412
01413 tile_lock (tile);
01414
01415 bpp = tile_bpp (tile);
01416
01417 for (i = 0; i < bpp; i++)
01418 {
01419 data = (guchar*) tile_data_pointer (tile, 0, 0) + i;
01420
01421 state = 0;
01422 length = 0;
01423 count = 0;
01424 size = tile_ewidth(tile) * tile_eheight(tile);
01425 last = -1;
01426
01427 while (size > 0)
01428 {
01429 switch (state)
01430 {
01431 case 0:
01432
01433
01434
01435 if ((length == 32768) ||
01436 ((size - length) <= 0) ||
01437 ((length > 1) && (last != *data)))
01438 {
01439 count += length;
01440 if (length >= 128)
01441 {
01442 rlebuf[len++] = 127;
01443 rlebuf[len++] = (length >> 8);
01444 rlebuf[len++] = length & 0x00FF;
01445 rlebuf[len++] = last;
01446 }
01447 else
01448 {
01449 rlebuf[len++] = length - 1;
01450 rlebuf[len++] = last;
01451 }
01452 size -= length;
01453 length = 0;
01454 }
01455 else if ((length == 1) && (last != *data))
01456 state = 1;
01457 break;
01458
01459 case 1:
01460
01461
01462
01463 if ((length == 32768) ||
01464 ((size - length) == 0) ||
01465 ((length > 0) && (last == *data) &&
01466 ((size - length) == 1 || last == data[bpp])))
01467 {
01468 count += length;
01469 state = 0;
01470
01471 if (length >= 128)
01472 {
01473 rlebuf[len++] = 255 - 127;
01474 rlebuf[len++] = (length >> 8);
01475 rlebuf[len++] = length & 0x00FF;
01476 }
01477 else
01478 {
01479 rlebuf[len++] = 255 - (length - 1);
01480 }
01481
01482 t = data - length * bpp;
01483 for (j = 0; j < length; j++)
01484 {
01485 rlebuf[len++] = *t;
01486 t += bpp;
01487 }
01488
01489 size -= length;
01490 length = 0;
01491 }
01492 break;
01493 }
01494
01495 if (size > 0) {
01496 length += 1;
01497 last = *data;
01498 data += bpp;
01499 }
01500 }
01501
01502 if (count != (tile_ewidth (tile) * tile_eheight (tile)))
01503 g_message ("xcf: uh oh! xcf rle tile saving error: %d", count);
01504 }
01505 xcf_write_int8_check_error (info, rlebuf, len);
01506 tile_release (tile, FALSE);
01507
01508 return TRUE;
01509 }
01510
01511 static bool
01512 xcf_save_parasite (XcfInfo *info,
01513 KisAnnotation *parasite,
01514 GError **error)
01515 {
01516 if (gimp_parasite_is_persistent (parasite))
01517 {
01518 GError *tmp_error = NULL;
01519
01520 xcf_write_string_check_error (info, ¶site->name, 1);
01521 xcf_write_int32_check_error (info, ¶site->flags, 1);
01522 xcf_write_int32_check_error (info, ¶site->size, 1);
01523 xcf_write_int8_check_error (info, parasite->data, parasite->size);
01524 }
01525
01526 return TRUE;
01527 }
01528
01529 typedef struct
01530 {
01531 XcfInfo *info;
01532 GError *error;
01533 } XcfParasiteData;
01534
01535 static void
01536 xcf_save_parasite_func (QCString *key,
01537 KisAnnotation *parasite,
01538 XcfParasiteData *data)
01539 {
01540 if (! data->error)
01541 xcf_save_parasite (data->info, parasite, &data->error);
01542 }
01543
01544 static bool
01545 xcf_save_parasite_list (XcfInfo *info,
01546 KisAnnotationList *list,
01547 GError **error)
01548 {
01549 XcfParasiteData data;
01550
01551 data.info = info;
01552 data.error = NULL;
01553
01554 gimp_parasite_list_foreach (list, (GHFunc) xcf_save_parasite_func, &data);
01555
01556 if (data.error)
01557 {
01558 g_propagate_error (error, data.error);
01559 return FALSE;
01560 }
01561
01562 return TRUE;
01563 }
01564
01565 static bool
01566 xcf_save_old_paths (XcfInfo *info,
01567 KisImage *gimage,
01568 GError **error)
01569 {
01570 GimpVectors *active_vectors;
01571 Q_INT32 num_paths;
01572 Q_INT32 active_index = 0;
01573 GList *list;
01574 GError *tmp_error = NULL;
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584 num_paths = gimp_container_num_children (gimage->vectors);
01585
01586 active_vectors = gimp_image_get_active_vectors (gimage);
01587
01588 if (active_vectors)
01589 active_index = gimp_container_get_child_index (gimage->vectors,
01590 GIMP_OBJECT (active_vectors));
01591
01592 xcf_write_int32_check_error (info, &active_index, 1);
01593 xcf_write_int32_check_error (info, &num_paths, 1);
01594
01595 for (list = GIMP_LIST (gimage->vectors)->list;
01596 list;
01597 list = g_list_next (list))
01598 {
01599 GimpVectors *vectors = list->data;
01600 QCString *name;
01601 Q_INT32 locked;
01602 Q_UINT8 state;
01603 Q_INT32 version;
01604 Q_INT32 pathtype;
01605 Q_INT32 tattoo;
01606 GimpVectorsCompatPoint *points;
01607 Q_INT3232 num_points;
01608 Q_INT3232 closed;
01609 Q_INT32 i;
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623 points = gimp_vectors_compat_get_points (vectors, &num_points, &closed);
01624
01625
01626
01627
01628
01629
01630 name = (QCString *) gimp_object_get_name (GIMP_OBJECT (vectors));
01631 locked = gimp_item_get_linked (GIMP_ITEM (vectors));
01632 state = closed ? 4 : 2;
01633 version = 3;
01634 pathtype = 1;
01635 tattoo = gimp_item_get_tattoo (GIMP_ITEM (vectors));
01636
01637 xcf_write_string_check_error (info, &name, 1);
01638 xcf_write_int32_check_error (info, &locked, 1);
01639 xcf_write_int8_check_error (info, &state, 1);
01640 xcf_write_int32_check_error (info, &closed, 1);
01641 xcf_write_int32_check_error (info, &num_points, 1);
01642 xcf_write_int32_check_error (info, &version, 1);
01643 xcf_write_int32_check_error (info, &pathtype, 1);
01644 xcf_write_int32_check_error (info, &tattoo, 1);
01645
01646 for (i = 0; i < num_points; i++)
01647 {
01648 float x;
01649 float y;
01650
01651 x = points[i].x;
01652 y = points[i].y;
01653
01654
01655
01656
01657
01658
01659
01660 xcf_write_int32_check_error (info, &points[i].type, 1);
01661 xcf_write_float_check_error (info, &x, 1);
01662 xcf_write_float_check_error (info, &y, 1);
01663 }
01664
01665 g_free (points);
01666 }
01667
01668 return TRUE;
01669 }
01670
01671 static bool
01672 xcf_save_vectors (XcfInfo *info,
01673 KisImage *gimage,
01674 GError **error)
01675 {
01676 GimpVectors *active_vectors;
01677 Q_INT32 version = 1;
01678 Q_INT32 active_index = 0;
01679 Q_INT32 num_paths;
01680 GList *list;
01681 GList *stroke_list;
01682 GError *tmp_error = NULL;
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693 active_vectors = gimp_image_get_active_vectors (gimage);
01694
01695 if (active_vectors)
01696 active_index = gimp_container_get_child_index (gimage->vectors,
01697 GIMP_OBJECT (active_vectors));
01698
01699 num_paths = gimp_container_num_children (gimage->vectors);
01700
01701 xcf_write_int32_check_error (info, &version, 1);
01702 xcf_write_int32_check_error (info, &active_index, 1);
01703 xcf_write_int32_check_error (info, &num_paths, 1);
01704
01705 for (list = GIMP_LIST (gimage->vectors)->list;
01706 list;
01707 list = g_list_next (list))
01708 {
01709 GimpVectors *vectors = list->data;
01710 KisAnnotationList *parasites;
01711 QCString *name;
01712 Q_INT32 tattoo;
01713 Q_INT32 visible;
01714 Q_INT32 linked;
01715 Q_INT32 num_parasites;
01716 Q_INT32 num_strokes;
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730 parasites = GIMP_ITEM (vectors)->parasites;
01731
01732 name = (QCString *) gimp_object_get_name (GIMP_OBJECT (vectors));
01733 visible = gimp_item_get_visible (GIMP_ITEM (vectors));
01734 linked = gimp_item_get_linked (GIMP_ITEM (vectors));
01735 tattoo = gimp_item_get_tattoo (GIMP_ITEM (vectors));
01736 num_parasites = gimp_parasite_list_persistent_length (parasites);
01737 num_strokes = g_list_length (vectors->strokes);
01738
01739 xcf_write_string_check_error (info, &name, 1);
01740 xcf_write_int32_check_error (info, &tattoo, 1);
01741 xcf_write_int32_check_error (info, &visible, 1);
01742 xcf_write_int32_check_error (info, &linked, 1);
01743 xcf_write_int32_check_error (info, &num_parasites, 1);
01744 xcf_write_int32_check_error (info, &num_strokes, 1);
01745
01746 xcf_check_error (xcf_save_parasite_list (info, parasites, error));
01747
01748 for (stroke_list = g_list_first (vectors->strokes);
01749 stroke_list;
01750 stroke_list = g_list_next (stroke_list))
01751 {
01752 GimpStroke *stroke;
01753 Q_INT32 stroke_type;
01754 Q_INT32 closed;
01755 Q_INT32 num_axes;
01756 GArray *control_points;
01757 Q_INT32 i;
01758
01759 Q_INT32 type;
01760 float coords[6];
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771 stroke = GIMP_STROKE (stroke_list->data);
01772
01773 if (GIMP_IS_BEZIER_STROKE (stroke))
01774 {
01775 stroke_type = XCF_STROKETYPE_BEZIER_STROKE;
01776 num_axes = 2;
01777 }
01778 else
01779 {
01780 g_printerr ("Skipping unknown stroke type!\n");
01781 continue;
01782 }
01783
01784 control_points = gimp_stroke_control_points_get (stroke, &closed);
01785
01786 xcf_write_int32_check_error (info, &stroke_type, 1);
01787 xcf_write_int32_check_error (info, &closed, 1);
01788 xcf_write_int32_check_error (info, &num_axes, 1);
01789 xcf_write_int32_check_error (info, &control_points->len, 1);
01790
01791 for (i = 0; i < control_points->len; i++)
01792 {
01793 GimpAnchor *anchor;
01794
01795 anchor = & (g_array_index (control_points, GimpAnchor, i));
01796
01797 type = anchor->type;
01798 coords[0] = anchor->position.x;
01799 coords[1] = anchor->position.y;
01800 coords[2] = anchor->position.pressure;
01801 coords[3] = anchor->position.xtilt;
01802 coords[4] = anchor->position.ytilt;
01803 coords[5] = anchor->position.wheel;
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817 xcf_write_int32_check_error (info, &type, 1);
01818 xcf_write_float_check_error (info, coords, num_axes);
01819 }
01820
01821 g_array_free (control_points, TRUE);
01822 }
01823 }
01824
01825 return TRUE;
01826 }