Ticket #2977: id3tag.patch

File id3tag.patch, 3.9 KB (added by myth@…, 5 years ago)

patch for bug

  • mythplugins/mythmusic/mythmusic/metaio_libid3hack.c

     
     1/** \file metaio_libid3hack.c 
     2    \brief Full featured id3_file_update implementation. 
     3 
     4    libid3tag (0.15.1b) id3_file_update doesn't handle ID3V2 tags that 
     5    are longer than then existing tag, this includes adding ID3v2 
     6    tags. Hence this file which is a cut'n'paste job of libid3tags 
     7    file.c, with the extra feaures and some tweaks like always 
     8    removing id3v1 tags. 
     9    
     10 */ 
    111#include <id3tag.h> 
    212 
    313#include <assert.h> 
     
    4050{ 
    4151  int result = 0; 
    4252  int file_size, overlap; 
     53  size_t location, data_start; 
    4354  char *buffer = NULL; 
    4455  int buffersize; 
    4556   
     
    4859 
    4960  assert(!data || length > 0); 
    5061 
    51   if (!data 
    52       || (!(file->ntags == 1 && !(file->flags & ID3_FILE_FLAG_ID3V1)) 
    53           && !(file->ntags == 2 &&  (file->flags & ID3_FILE_FLAG_ID3V1)))) { 
    54     /* no v2 tag. we should create one */ 
    55      
    56     /* ... */ 
    57      
    58     goto done; 
     62  if ((file->ntags == 1 && !(file->flags & ID3_FILE_FLAG_ID3V1)) || file->ntags >= 2) { 
     63      overlap = length - file->tags[0].length; 
     64      location = file->tags[0].location; 
     65      data_start = file->tags[0].location + file->tags[0].length; 
     66  } else { 
     67      overlap = length; 
     68      location = 0; 
     69      data_start = 0; 
    5970  } 
    6071 
    61   if (file->tags[0].length == length) { 
     72  if (overlap == 0) { 
    6273    /* easy special case: rewrite existing tag in-place */ 
    6374 
    64     if (fseek(file->iofile, file->tags[0].location, SEEK_SET) == -1 || 
     75    if (fseek(file->iofile, location, SEEK_SET) == -1 || 
    6576        fwrite(data, length, 1, file->iofile) != 1 || 
    6677        fflush(file->iofile) == EOF) 
    6778      return -1; 
     
    7586  /* calculate the difference in tag sizes. 
    7687   * we'll need at least double this difference to write the file again using  
    7788   * optimal memory allocation, but avoiding a temporary file. 
    78    */ 
    79   overlap = length - file->tags[0].length; 
     89   */   
    8090   
    8191  if (overlap > 0) { 
    8292    buffersize = overlap*2; 
     
    97107  file_size = ftell(file->iofile); 
    98108   
    99109  /* Seek to start of data */ 
    100   if (-1 == fseek(file->iofile, file->tags[0].location + file->tags[0].length, 
    101                   SEEK_SET)) 
     110  if (-1 == fseek(file->iofile, data_start, SEEK_SET)) 
    102111    goto fail; 
    103112   
    104113  /* fill our buffer, if needed */ 
     
    108117  } 
    109118   
    110119  /* write the tag where the old one was */ 
    111   if (-1 == fseek(file->iofile, file->tags[0].location, SEEK_SET) 
     120  if (-1 == fseek(file->iofile, location, SEEK_SET) 
    112121      || 1 != fwrite(data, length, 1, file->iofile)) 
    113122    goto fail; 
    114123   
     
    190199  /* truncate if required */ 
    191200  if (ftell(file->iofile) < file_size) 
    192201    ftruncate(fileno(file->iofile), ftell(file->iofile)); 
    193       
     202 
    194203  if (0) { 
    195204  fail: 
    196205    if (buffer) free(buffer); 
     
    214223  assert(file); 
    215224 
    216225  if (file->mode != ID3_FILE_MODE_READWRITE) 
    217     return -1; 
     226    return -1;   
    218227 
    219228  options = id3_tag_options(file->primary, 0, 0); 
    220229 
     
    224233 
    225234  v2size = id3_tag_render(file->primary, 0); 
    226235  if (v2size) { 
    227     id3v2 = malloc(v2size); 
     236      id3v2 = (id3_byte_t*)malloc(v2size); 
    228237    if (id3v2 == 0) 
    229238      goto fail; 
    230239 
     
    240249  if (myth_v2_write(file, id3v2, v2size) == -1) 
    241250    goto fail; 
    242251 
     252  /* If ID3v1 tag present (flag set and 'TAG' at size-128 bytes), 
     253   * remove it by truncating. 
     254   */ 
     255  if (file->flags & ID3_FILE_FLAG_ID3V1) { 
     256      char tag[3]; 
     257      if (fseek (file->iofile, -128, SEEK_END) != 0 || 
     258          fread (tag, sizeof(tag), 1, file->iofile) != 1) 
     259          goto fail; 
     260      if (memcmp (tag, "TAG", sizeof (tag)) == 0) 
     261          ftruncate (fileno (file->iofile), ftell (file->iofile) - 3); 
     262      file->flags ^= ID3_FILE_FLAG_ID3V1; 
     263  } 
     264 
    243265  rewind(file->iofile); 
    244266 
    245267  /* update file tags array? ... */