# HG changeset patch
# User Thomas Bernard <miniupnp@free.fr>
# Date 1543580822 -3600
# Fri Nov 30 13:27:02 2018 +0100
# Branch SDL-1.2
# Node ID bc52bac7f250ad3c6fd31a5d16aa2d6ea36412f1
# Parent 988994bae873408c09ec5e635c7c372c9abe2048
support for XCF files version 11 (64 bits offsets)
diff -r 988994bae873 -r bc52bac7f250 IMG_xcf.c
a
|
b
|
|
143 | 143 | |
144 | 144 | typedef struct { |
145 | 145 | char sign [14]; |
| 146 | Uint32 file_version; |
146 | 147 | Uint32 width; |
147 | 148 | Uint32 height; |
148 | 149 | Sint32 image_type; |
| 150 | Uint32 precision; |
149 | 151 | xcf_prop * properties; |
150 | 152 | |
151 | 153 | Uint32 * layer_file_offsets; |
… |
… |
|
254 | 256 | return data; |
255 | 257 | } |
256 | 258 | |
| 259 | static Uint64 read_offset (SDL_RWops * src, const xcf_header * h) { |
| 260 | Uint64 offset; // starting with version 11, offsets are 64 bits |
| 261 | offset = (h->file_version >= 11) ? (Uint64)SDL_ReadBE32 (src) << 32 : 0; |
| 262 | offset |= SDL_ReadBE32 (src); |
| 263 | return offset; |
| 264 | } |
| 265 | |
257 | 266 | |
258 | 267 | static Uint32 Swap32 (Uint32 v) { |
259 | 268 | return |
… |
… |
|
327 | 336 | h->width = SDL_ReadBE32 (src); |
328 | 337 | h->height = SDL_ReadBE32 (src); |
329 | 338 | h->image_type = SDL_ReadBE32 (src); |
| 339 | h->file_version = (h->sign[10] - '0') * 100 + (h->sign[11] - '0') * 10 + (h->sign[12] - '0'); |
330 | 340 | #ifdef DEBUG |
331 | | printf ("XCF signature : %.14s\n", h->sign); |
| 341 | printf ("XCF signature : %.14s (version %u)\n", h->sign, h->file_version); |
332 | 342 | printf (" (%u,%u) type=%u\n", h->width, h->height, h->image_type); |
333 | 343 | #endif |
| 344 | if (h->file_version >= 4) |
| 345 | h->precision = SDL_ReadBE32 (src); |
| 346 | else |
| 347 | h->precision = 150; |
334 | 348 | |
335 | 349 | h->properties = NULL; |
336 | 350 | h->layer_file_offsets = NULL; |
… |
… |
|
375 | 389 | free (l); |
376 | 390 | } |
377 | 391 | |
378 | | static xcf_layer * read_xcf_layer (SDL_RWops * src) { |
| 392 | static xcf_layer * read_xcf_layer (SDL_RWops * src, const xcf_header * h) { |
379 | 393 | xcf_layer * l; |
380 | 394 | xcf_prop prop; |
381 | 395 | |
… |
… |
|
385 | 399 | l->layer_type = SDL_ReadBE32 (src); |
386 | 400 | |
387 | 401 | l->name = read_string (src); |
| 402 | #ifdef DEBUG |
| 403 | printf ("layer (%d,%d) type=%d '%s'\n", l->width, l->height, l->layer_type, l->name); |
| 404 | #endif |
388 | 405 | |
389 | 406 | do { |
390 | 407 | if (!xcf_read_property (src, &prop)) { |
… |
… |
|
399 | 416 | } |
400 | 417 | } while (prop.id != PROP_END); |
401 | 418 | |
402 | | l->hierarchy_file_offset = SDL_ReadBE32 (src); |
403 | | l->layer_mask_offset = SDL_ReadBE32 (src); |
| 419 | l->hierarchy_file_offset = read_offset (src, h); |
| 420 | l->layer_mask_offset = read_offset (src, h); |
404 | 421 | |
405 | 422 | return l; |
406 | 423 | } |
… |
… |
|
419 | 436 | l->height = SDL_ReadBE32 (src); |
420 | 437 | |
421 | 438 | l->name = read_string (src); |
| 439 | #ifdef DEBUG |
| 440 | printf ("channel (%u,%u) '%s'\n", l->width, l->height, l->name); |
| 441 | #endif |
422 | 442 | |
423 | 443 | l->selection = 0; |
424 | 444 | do { |
… |
… |
|
829 | 849 | |
830 | 850 | offsets = 0; |
831 | 851 | |
832 | | while ((offset = SDL_ReadBE32 (src))) { |
| 852 | while ((offset = read_offset (src, head))) { |
833 | 853 | head->layer_file_offsets = (Uint32 *) realloc (head->layer_file_offsets, sizeof (Uint32) * (offsets+1)); |
834 | 854 | head->layer_file_offsets [offsets] = (Uint32)offset; |
835 | 855 | offsets++; |
… |
… |
|
849 | 869 | SDL_Rect rs, rd; |
850 | 870 | SDL_RWseek (src, head->layer_file_offsets [i-1], RW_SEEK_SET); |
851 | 871 | |
852 | | layer = read_xcf_layer (src); |
853 | | do_layer_surface (lays, src, head, layer, load_tile); |
854 | | rs.x = 0; |
855 | | rs.y = 0; |
856 | | rs.w = layer->width; |
857 | | rs.h = layer->height; |
858 | | rd.x = layer->offset_x; |
859 | | rd.y = layer->offset_y; |
860 | | rd.w = layer->width; |
861 | | rd.h = layer->height; |
| 872 | layer = read_xcf_layer (src, head); |
| 873 | if (layer != NULL) { |
| 874 | do_layer_surface (lays, src, head, layer, load_tile); |
| 875 | rs.x = 0; |
| 876 | rs.y = 0; |
| 877 | rs.w = layer->width; |
| 878 | rs.h = layer->height; |
| 879 | rd.x = layer->offset_x; |
| 880 | rd.y = layer->offset_y; |
| 881 | rd.w = layer->width; |
| 882 | rd.h = layer->height; |
862 | 883 | |
863 | | if (layer->visible) |
864 | | SDL_BlitSurface (lays, &rs, surface, &rd); |
865 | | free_xcf_layer (layer); |
| 884 | if (layer->visible) |
| 885 | SDL_BlitSurface (lays, &rs, surface, &rd); |
| 886 | free_xcf_layer (layer); |
| 887 | } |
866 | 888 | } |
867 | 889 | |
868 | 890 | SDL_FreeSurface (lays); |
… |
… |
|
872 | 894 | // read channels |
873 | 895 | channel = NULL; |
874 | 896 | chnls = 0; |
875 | | while ((offset = SDL_ReadBE32 (src))) { |
| 897 | while ((offset = read_offset (src, head))) { |
876 | 898 | channel = (xcf_channel **) realloc (channel, sizeof (xcf_channel *) * (chnls+1)); |
877 | 899 | fp = SDL_RWtell (src); |
878 | 900 | SDL_RWseek (src, offset, RW_SEEK_SET); |
879 | | channel [chnls++] = (read_xcf_channel (src)); |
| 901 | channel [chnls] = (read_xcf_channel (src)); |
| 902 | if (channel [chnls] != NULL) |
| 903 | chnls++; |
880 | 904 | SDL_RWseek (src, fp, RW_SEEK_SET); |
881 | 905 | } |
882 | 906 | |