Ticket #2977: id3tag.patch
File id3tag.patch, 3.9 KB (added by , 17 years ago) |
---|
-
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 */ 1 11 #include <id3tag.h> 2 12 3 13 #include <assert.h> … … 40 50 { 41 51 int result = 0; 42 52 int file_size, overlap; 53 size_t location, data_start; 43 54 char *buffer = NULL; 44 55 int buffersize; 45 56 … … 48 59 49 60 assert(!data || length > 0); 50 61 51 if ( !data52 || (!(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; 59 70 } 60 71 61 if ( file->tags[0].length == length) {72 if (overlap == 0) { 62 73 /* easy special case: rewrite existing tag in-place */ 63 74 64 if (fseek(file->iofile, file->tags[0].location, SEEK_SET) == -1 ||75 if (fseek(file->iofile, location, SEEK_SET) == -1 || 65 76 fwrite(data, length, 1, file->iofile) != 1 || 66 77 fflush(file->iofile) == EOF) 67 78 return -1; … … 75 86 /* calculate the difference in tag sizes. 76 87 * we'll need at least double this difference to write the file again using 77 88 * optimal memory allocation, but avoiding a temporary file. 78 */ 79 overlap = length - file->tags[0].length; 89 */ 80 90 81 91 if (overlap > 0) { 82 92 buffersize = overlap*2; … … 97 107 file_size = ftell(file->iofile); 98 108 99 109 /* 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)) 102 111 goto fail; 103 112 104 113 /* fill our buffer, if needed */ … … 108 117 } 109 118 110 119 /* 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) 112 121 || 1 != fwrite(data, length, 1, file->iofile)) 113 122 goto fail; 114 123 … … 190 199 /* truncate if required */ 191 200 if (ftell(file->iofile) < file_size) 192 201 ftruncate(fileno(file->iofile), ftell(file->iofile)); 193 202 194 203 if (0) { 195 204 fail: 196 205 if (buffer) free(buffer); … … 214 223 assert(file); 215 224 216 225 if (file->mode != ID3_FILE_MODE_READWRITE) 217 return -1; 226 return -1; 218 227 219 228 options = id3_tag_options(file->primary, 0, 0); 220 229 … … 224 233 225 234 v2size = id3_tag_render(file->primary, 0); 226 235 if (v2size) { 227 id3v2 =malloc(v2size);236 id3v2 = (id3_byte_t*)malloc(v2size); 228 237 if (id3v2 == 0) 229 238 goto fail; 230 239 … … 240 249 if (myth_v2_write(file, id3v2, v2size) == -1) 241 250 goto fail; 242 251 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 243 265 rewind(file->iofile); 244 266 245 267 /* update file tags array? ... */