Ticket #88: SDL_image_XCF_v11.hg.patch

File SDL_image_XCF_v11.hg.patch, 4.3 KB (added by Thomas Bernard, 5 years ago)

patch for SDL_image 1.2 : support for XCF version >= 11 (64bits offsets)

  • IMG_xcf.c

    # 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  
    143143
    144144typedef struct {
    145145  char   sign [14];
     146  Uint32 file_version;
    146147  Uint32 width;
    147148  Uint32 height;
    148149  Sint32 image_type;
     150  Uint32 precision;
    149151  xcf_prop * properties;
    150152
    151153  Uint32 * layer_file_offsets;
     
    254256  return data;
    255257}
    256258
     259static 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
    257266
    258267static Uint32 Swap32 (Uint32 v) {
    259268  return
     
    327336  h->width       = SDL_ReadBE32 (src);
    328337  h->height      = SDL_ReadBE32 (src);
    329338  h->image_type  = SDL_ReadBE32 (src);
     339  h->file_version = (h->sign[10] - '0') * 100 + (h->sign[11] - '0') * 10 + (h->sign[12] - '0');
    330340#ifdef DEBUG
    331   printf ("XCF signature : %.14s\n", h->sign);
     341  printf ("XCF signature : %.14s (version %u)\n", h->sign, h->file_version);
    332342  printf (" (%u,%u) type=%u\n", h->width, h->height, h->image_type);
    333343#endif
     344  if (h->file_version >= 4)
     345    h->precision = SDL_ReadBE32 (src);
     346  else
     347    h->precision = 150;
    334348
    335349  h->properties = NULL;
    336350  h->layer_file_offsets = NULL;
     
    375389  free (l);
    376390}
    377391
    378 static xcf_layer * read_xcf_layer (SDL_RWops * src) {
     392static xcf_layer * read_xcf_layer (SDL_RWops * src, const xcf_header * h) {
    379393  xcf_layer * l;
    380394  xcf_prop    prop;
    381395
     
    385399  l->layer_type = SDL_ReadBE32 (src);
    386400
    387401  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
    388405
    389406  do {
    390407    if (!xcf_read_property (src, &prop)) {
     
    399416    }
    400417  } while (prop.id != PROP_END);
    401418
    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);
    404421
    405422  return l;
    406423}
     
    419436  l->height = SDL_ReadBE32 (src);
    420437
    421438  l->name = read_string (src);
     439#ifdef DEBUG
     440  printf ("channel (%u,%u) '%s'\n", l->width, l->height, l->name);
     441#endif
    422442
    423443  l->selection = 0;
    424444  do {
     
    829849
    830850  offsets = 0;
    831851
    832   while ((offset = SDL_ReadBE32 (src))) {
     852  while ((offset = read_offset (src, head))) {
    833853    head->layer_file_offsets = (Uint32 *) realloc (head->layer_file_offsets, sizeof (Uint32) * (offsets+1));
    834854    head->layer_file_offsets [offsets] = (Uint32)offset;
    835855    offsets++;
     
    849869    SDL_Rect rs, rd;
    850870    SDL_RWseek (src, head->layer_file_offsets [i-1], RW_SEEK_SET);
    851871
    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;
    862883
    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    }
    866888  }
    867889
    868890  SDL_FreeSurface (lays);
     
    872894  // read channels
    873895  channel = NULL;
    874896  chnls   = 0;
    875   while ((offset = SDL_ReadBE32 (src))) {
     897  while ((offset = read_offset (src, head))) {
    876898    channel = (xcf_channel **) realloc (channel, sizeof (xcf_channel *) * (chnls+1));
    877899    fp = SDL_RWtell (src);
    878900    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++;
    880904    SDL_RWseek (src, fp, RW_SEEK_SET);   
    881905  }
    882906