Ticket #2977: id3tag.patch

File id3tag.patch, 3.9 KB (added by myth@…, 13 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? ... */