1
2 /**********************************************************
3 * libmp3splt -- library based on mp3splt,
4 * for mp3/ogg splitting without decoding
5 *
6 * Copyright (c) 2002-2005 M. Trotta - <mtrotta@users.sourceforge.net>
7 * Copyright (c) 2005-2014 Alexandru Munteanu - m@ioalex.net
8 *
9 *********************************************************/
10
11 /**********************************************************
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
25 * USA.
26 *********************************************************/
27
28 #include <string.h>
29
30 #include "splt.h"
31 #include "tags_utils.h"
32
33 static void splt_tu_copy_tags_without_original_and_version(splt_tags *from, splt_tags *to,
34 int *error);
35
splt_tu_free_original_tags(splt_state * state)36 void splt_tu_free_original_tags(splt_state *state)
37 {
38 splt_tags *tags = &state->original_tags.tags;
39 splt_tu_free_one_tags_content(tags);
40 int err = SPLT_OK;
41 splt_p_clear_original_tags(state, &err);
42 }
43
splt_tu_get_tags_group(splt_state * state)44 splt_tags_group *splt_tu_get_tags_group(splt_state *state)
45 {
46 return state->split.tags_group;
47 }
48
splt_tu_duplicate_tags(splt_state * state,splt_code * error,int * tags_number)49 static splt_tags *splt_tu_duplicate_tags(splt_state *state, splt_code *error, int *tags_number)
50 {
51 *tags_number = 0;
52
53 if (state->split.tags_group == NULL) { return NULL; }
54
55 int total_tags = state->split.tags_group->real_tagsnumber;
56 if (total_tags == 0) { return NULL; }
57
58 splt_tags *tags = malloc(sizeof(splt_tags) * total_tags);
59 if (tags == NULL)
60 {
61 *error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
62 return NULL;
63 }
64
65 int i = 0;
66 for (i = 0;i < total_tags;i++)
67 {
68 splt_tu_reset_tags(&tags[i]);
69 splt_tu_copy_tags(&state->split.tags_group->tags[i], &tags[i], error);
70 (*tags_number)++;
71
72 if (*error < 0)
73 {
74 int j = 0;
75 for (j = 0; i < i; j++) { splt_tu_free_one_tags_content(&tags[i]); }
76 *tags_number = 0;
77 return NULL;
78 }
79 }
80
81 return tags;
82 }
83
splt_tu_auto_increment_tracknumber(splt_state * state)84 void splt_tu_auto_increment_tracknumber(splt_state *state)
85 {
86 int current_split = splt_t_get_current_split_file_number(state) - 1;
87 int old_current_split = current_split;
88
89 int remaining_tags_like_x = splt_o_get_int_option(state, SPLT_OPT_ALL_REMAINING_TAGS_LIKE_X);
90 if (remaining_tags_like_x == -1)
91 {
92 return;
93 }
94
95 int real_tags_number = 0;
96 if (state->split.tags_group)
97 {
98 real_tags_number = state->split.tags_group->real_tagsnumber;
99 }
100
101 if (current_split >= real_tags_number)
102 {
103 current_split = remaining_tags_like_x;
104 }
105
106 if (splt_o_get_int_option(state, SPLT_OPT_AUTO_INCREMENT_TRACKNUMBER_TAGS) <= 0)
107 {
108 return;
109 }
110
111 if (current_split != remaining_tags_like_x)
112 {
113 return;
114 }
115
116 if ((old_current_split > 0) &&
117 (old_current_split-1 < real_tags_number) &&
118 (old_current_split != remaining_tags_like_x))
119 {
120 const int *prev_track = splt_tu_get_tags_field(state, old_current_split - 1, SPLT_TAGS_TRACK);
121 int previous_track = 0;
122 if (prev_track != NULL)
123 {
124 previous_track = *prev_track;
125 }
126 splt_tu_set_tags_field(state, remaining_tags_like_x, SPLT_TAGS_TRACK, &previous_track);
127
128 splt_tags *tags_like_x = splt_tu_get_tags_like_x(state);
129 tags_like_x->was_auto_incremented = SPLT_TRUE;
130 }
131
132 if (old_current_split != current_split)
133 {
134 int tracknumber = 1;
135 if (splt_tu_tags_exists(state, current_split))
136 {
137 const int *track = splt_tu_get_tags_field(state, current_split, SPLT_TAGS_TRACK);
138 if (track != NULL)
139 {
140 tracknumber = *track;
141 }
142 }
143 int new_tracknumber = tracknumber + 1;
144 splt_tu_set_tags_field(state, current_split, SPLT_TAGS_TRACK, &new_tracknumber);
145 splt_tags *tags = splt_tu_get_tags_at(state, current_split);
146 tags->was_auto_incremented = SPLT_TRUE;
147
148 splt_tu_set_like_x_tags_field(state, SPLT_TAGS_TRACK, &new_tracknumber);
149
150 splt_tags *tags_like_x = splt_tu_get_tags_like_x(state);
151 tags_like_x->was_auto_incremented = SPLT_TRUE;
152 }
153 }
154
splt_tu_get_original_tags(splt_state * state,int * err)155 void splt_tu_get_original_tags(splt_state *state, int *err)
156 {
157 if (! splt_io_input_is_stdin(state))
158 {
159 splt_tu_free_original_tags(state);
160 splt_p_set_original_tags(state, err);
161 }
162 }
163
splt_tu_append_tags(splt_state * state,const char * title,const char * artist,const char * album,const char * performer,const char * year,const char * comment,int track,const char * genre,int set_original_tags)164 int splt_tu_append_tags(splt_state *state,
165 const char *title, const char *artist,
166 const char *album, const char *performer,
167 const char *year, const char *comment,
168 int track, const char *genre, int set_original_tags)
169 {
170 int error = SPLT_OK;
171 int old_tagsnumber = 0;
172 if (state->split.tags_group)
173 {
174 old_tagsnumber = state->split.tags_group->real_tagsnumber;
175 }
176
177 error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_TITLE, title);
178 if (error != SPLT_OK)
179 return error;
180
181 error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_ARTIST, artist);
182 if (error != SPLT_OK)
183 return error;
184
185 error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_ALBUM, album);
186 if (error != SPLT_OK)
187 return error;
188
189 error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_PERFORMER, performer);
190 if (error != SPLT_OK)
191 return error;
192
193 error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_YEAR, year);
194 if (error != SPLT_OK)
195 return error;
196
197 error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_COMMENT, comment);
198 if (error != SPLT_OK)
199 return error;
200
201 error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_TRACK, &track);
202 if (error != SPLT_OK)
203 return error;
204
205 error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_ORIGINAL, &set_original_tags);
206 if (error != SPLT_OK)
207 return error;
208
209 error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_GENRE, genre);
210 return error;
211 }
212
splt_tu_set_char_field_on_tag(splt_tags * tags,splt_tag_key key,const char * value)213 int splt_tu_set_char_field_on_tag(splt_tags *tags, splt_tag_key key, const char *value)
214 {
215 if (key == SPLT_TAGS_TRACK)
216 {
217 int track = atoi(value);
218 return splt_tu_set_field_on_tags(tags, key, &track);
219 }
220
221 if (key == SPLT_TAGS_ORIGINAL)
222 {
223 if (strcmp("true", value) == 0)
224 {
225 int true_value = SPLT_TRUE;
226 return splt_tu_set_field_on_tags(tags, key, &true_value);
227 }
228
229 int false_value = SPLT_FALSE;
230 return splt_tu_set_field_on_tags(tags, key, &false_value);
231 }
232
233 return splt_tu_set_field_on_tags(tags, key, value);
234 }
235
splt_tu_append_original_tags(splt_state * state)236 int splt_tu_append_original_tags(splt_state *state)
237 {
238 int err = SPLT_OK;
239
240 char *new_title = NULL;
241 char *new_artist = NULL;
242 char *new_album = NULL;
243 char *new_year = NULL;
244 char *new_comment = NULL;
245 char *new_genre = NULL;
246
247 splt_tags *tags = &state->original_tags.tags;
248
249 new_title = splt_su_replace_all(tags->title, "@", "@@", &err);
250 if (err != SPLT_OK) { goto end; }
251
252 new_artist = splt_su_replace_all(tags->artist, "@", "@@", &err);
253 if (err != SPLT_OK) { goto end; }
254
255 new_album = splt_su_replace_all(tags->album, "@", "@@", &err);
256 if (err != SPLT_OK) { goto end; }
257
258 new_year = splt_su_replace_all(tags->year, "@", "@@", &err);
259 if (err != SPLT_OK) { goto end; }
260
261 new_comment = splt_su_replace_all(tags->comment, "@", "@@", &err);
262 if (err != SPLT_OK) { goto end; }
263
264 new_genre = splt_su_replace_all(tags->genre, "@", "@@", &err);
265 if (err != SPLT_OK) { goto end; }
266
267 err = splt_tu_append_tags(state, new_title, new_artist, new_album, NULL,
268 new_year, new_comment, tags->track, new_genre, SPLT_TRUE);
269
270 end:
271 if (new_title) { free(new_title); }
272 if (new_artist) { free(new_artist); }
273 if (new_album) { free(new_album); }
274 if (new_year) { free(new_year); }
275 if (new_comment) { free(new_comment); }
276 if (new_genre) { free(new_genre); }
277
278 return err;
279 }
280
splt_tu_append_only_non_null_previous_tags(splt_state * state,const char * title,const char * artist,const char * album,const char * performer,const char * year,const char * comment,int track,const char * genre,int set_original_tags)281 int splt_tu_append_only_non_null_previous_tags(splt_state *state,
282 const char *title, const char *artist,
283 const char *album, const char *performer,
284 const char *year, const char *comment,
285 int track, const char *genre, int set_original_tags)
286 {
287 int error = SPLT_OK;
288 int old_tagsnumber = 0;
289 if (state->split.tags_group)
290 {
291 old_tagsnumber = state->split.tags_group->real_tagsnumber - 1;
292 }
293
294 if (old_tagsnumber < 0)
295 {
296 return error;
297 }
298
299 if (title != NULL)
300 {
301 error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_TITLE, title);
302 if (error != SPLT_OK) { return error; }
303 }
304
305 if (artist != NULL)
306 {
307 error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_ARTIST, artist);
308 if (error != SPLT_OK) { return error; }
309 }
310
311 if (album != NULL)
312 {
313 error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_ALBUM, album);
314 if (error != SPLT_OK) { return error; }
315 }
316
317 if (performer != NULL)
318 {
319 error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_PERFORMER, performer);
320 if (error != SPLT_OK) { return error; }
321 }
322
323 if (year != NULL)
324 {
325 error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_YEAR, year);
326 if (error != SPLT_OK) { return error; }
327 }
328
329 if (comment != NULL)
330 {
331 error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_COMMENT, comment);
332 if (error != SPLT_OK) { return error; }
333 }
334
335 if (track != -1)
336 {
337 error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_TRACK, &track);
338 if (error != SPLT_OK) { return error; }
339 }
340
341 if (set_original_tags != -1)
342 {
343 error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_ORIGINAL, &set_original_tags);
344 if (error != SPLT_OK) { return error; }
345 }
346
347 if (genre != NULL)
348 {
349 error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_GENRE, genre);
350 }
351
352 return error;
353 }
354
splt_tu_reset_tags(splt_tags * tags)355 void splt_tu_reset_tags(splt_tags *tags)
356 {
357 tags->title = NULL;
358 tags->artist = NULL;
359 tags->album = NULL;
360 tags->performer = NULL;
361 tags->year = NULL;
362 tags->comment = NULL;
363 tags->track = -1;
364 tags->genre = NULL;
365 tags->tags_version = 0;
366 tags->set_original_tags = SPLT_FALSE;
367 tags->was_auto_incremented = SPLT_FALSE;
368 }
369
splt_tu_new_tags(int * error)370 splt_tags *splt_tu_new_tags(int *error)
371 {
372 splt_tags *tags = malloc(sizeof(splt_tags));
373
374 if (tags == NULL)
375 {
376 *error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
377 return NULL;
378 }
379
380 memset(tags, '\0', sizeof(splt_tags));
381
382 splt_tu_reset_tags(tags);
383
384 return tags;
385 }
386
splt_tu_set_empty_tags(splt_state * state,int index)387 static void splt_tu_set_empty_tags(splt_state *state, int index)
388 {
389 splt_tu_reset_tags(&state->split.tags_group->tags[index]);
390 }
391
splt_tu_new_tags_if_necessary(splt_state * state,int index)392 int splt_tu_new_tags_if_necessary(splt_state *state, int index)
393 {
394 int error = SPLT_OK;
395
396 if (!state->split.tags_group)
397 {
398 if (index != 0)
399 {
400 splt_e_error(SPLT_IERROR_INT,__func__, index, NULL);
401 }
402 else
403 {
404 state->split.tags_group = malloc(sizeof(splt_tags_group));
405 if (state->split.tags_group == NULL)
406 {
407 return SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
408 }
409
410 state->split.tags_group->real_tagsnumber = 0;
411 state->split.tags_group->iterator_counter = 0;
412
413 state->split.tags_group->tags = splt_tu_new_tags(&error);
414 if (error < 0)
415 {
416 free(state->split.tags_group);
417 state->split.tags_group = NULL;
418 return error;
419 }
420
421 splt_tu_set_empty_tags(state, index);
422 state->split.tags_group->real_tagsnumber++;
423 }
424 }
425 else
426 {
427 if ((index > state->split.tags_group->real_tagsnumber) || (index < 0))
428 {
429 splt_e_error(SPLT_IERROR_INT,__func__, index, NULL);
430 }
431 else
432 {
433 if (index == state->split.tags_group->real_tagsnumber)
434 {
435 if ((state->split.tags_group->tags =
436 realloc(state->split.tags_group->tags, sizeof(splt_tags) * (index+1))) == NULL)
437 {
438 error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
439 return error;
440 }
441 else
442 {
443 splt_tu_set_empty_tags(state,index);
444 state->split.tags_group->real_tagsnumber++;
445 }
446 }
447 }
448 }
449
450 return error;
451 }
452
splt_tu_tags_exists(splt_state * state,int index)453 int splt_tu_tags_exists(splt_state *state, int index)
454 {
455 if (!state->split.tags_group)
456 {
457 return SPLT_FALSE;
458 }
459
460 if ((index >= 0) && (index < state->split.tags_group->real_tagsnumber))
461 {
462 return SPLT_TRUE;
463 }
464
465 return SPLT_FALSE;
466 }
467
splt_tu_set_tags_field(splt_state * state,int index,int tags_field,const void * data)468 int splt_tu_set_tags_field(splt_state *state, int index,
469 int tags_field, const void *data)
470 {
471 int error = SPLT_OK;
472
473 error = splt_tu_new_tags_if_necessary(state,index);
474 if (error != SPLT_OK) { return error; }
475
476 if (!state->split.tags_group ||
477 (index >= state->split.tags_group->real_tagsnumber) ||
478 (index < 0))
479 {
480 error = SPLT_ERROR_INEXISTENT_SPLITPOINT;
481 splt_e_error(SPLT_IERROR_INT,__func__, index, NULL);
482 return error;
483 }
484
485 splt_tu_set_field_on_tags(&state->split.tags_group->tags[index], tags_field, data);
486 if (error != SPLT_OK)
487 {
488 splt_e_error(SPLT_IERROR_INT,__func__, index, NULL);
489 }
490
491 return error;
492 }
493
splt_tu_set_like_x_tags_field(splt_state * state,int tags_field,const void * data)494 int splt_tu_set_like_x_tags_field(splt_state *state, int tags_field, const void *data)
495 {
496 return splt_tu_set_field_on_tags(&state->split.tags_like_x, tags_field, data);
497 }
498
splt_tu_set_original_tags_field(splt_state * state,int tags_field,const void * data)499 int splt_tu_set_original_tags_field(splt_state *state, int tags_field, const void *data)
500 {
501 return splt_tu_set_field_on_tags(&state->original_tags.tags, tags_field, data);
502 }
503
splt_tu_set_to_original_tags(splt_state * state,splt_tags * tags,int * error)504 void splt_tu_set_to_original_tags(splt_state *state, splt_tags *tags, int *error)
505 {
506 splt_tu_copy_tags_without_original_and_version(tags, &state->original_tags.tags, error);
507 }
508
splt_tu_set_original_tags_data(splt_state * state,void * data)509 void splt_tu_set_original_tags_data(splt_state *state, void *data)
510 {
511 state->original_tags.all_original_tags = data;
512 }
513
splt_tu_get_original_tags_data(splt_state * state)514 void *splt_tu_get_original_tags_data(splt_state *state)
515 {
516 return state->original_tags.all_original_tags;
517 }
518
splt_tu_get_original_tags_last_plugin_used(splt_state * state)519 int splt_tu_get_original_tags_last_plugin_used(splt_state *state)
520 {
521 return state->original_tags.last_plugin_used;
522 }
523
splt_tu_set_original_tags_last_plugin_used(splt_state * state,int plugin_used)524 void splt_tu_set_original_tags_last_plugin_used(splt_state *state, int plugin_used)
525 {
526 state->original_tags.last_plugin_used = plugin_used;
527 }
528
splt_tu_get_original_tags_tags(splt_state * state)529 splt_tags *splt_tu_get_original_tags_tags(splt_state *state)
530 {
531 return &state->original_tags.tags;
532 }
533
splt_tu_get_replaced_with_tags(const char * word,const splt_tags * tags,const splt_tags * original_tags,int track,int * error,int replace_tags_in_tags,int current_split,splt_state * state)534 static char *splt_tu_get_replaced_with_tags(const char *word,
535 const splt_tags *tags, const splt_tags *original_tags,
536 int track, int *error, int replace_tags_in_tags,
537 int current_split, splt_state *state)
538 {
539 int err = SPLT_OK;
540
541 if (current_split == -1)
542 {
543 current_split = splt_t_get_current_split_file_number(state) - 1;
544 }
545
546 long mins = -1; long secs = -1; long hundr = -1;
547 long point_value = splt_sp_get_splitpoint_value(state, current_split, &err);
548 splt_co_get_mins_secs_hundr(point_value, &mins, &secs, &hundr);
549 long next_mins = -1; long next_secs = -1; long next_hundr = -1;
550 long next_point_value = -1;
551 if (splt_sp_splitpoint_exists(state, current_split + 1))
552 {
553 next_point_value = splt_sp_get_splitpoint_value(state, current_split + 1, &err);
554 long total_time = splt_t_get_total_time(state);
555 if (total_time > 0 && next_point_value > total_time)
556 {
557 next_point_value = total_time;
558 }
559 splt_co_get_mins_secs_hundr(next_point_value, &next_mins, &next_secs, &next_hundr);
560 }
561 short write_eof = SPLT_FALSE;
562 if (next_point_value == LONG_MAX)
563 {
564 write_eof = SPLT_TRUE;
565 }
566
567 long mMsShH_value = 1;
568 short eof_written = SPLT_FALSE;
569
570 char *word_with_tags = NULL;
571
572 if (!replace_tags_in_tags)
573 {
574 err = splt_su_copy(word, &word_with_tags);
575 if (err < 0) { *error = err; }
576 return word_with_tags;
577 }
578
579 char buffer[256] = { '\0' };
580
581 if (word == NULL)
582 {
583 return NULL;
584 }
585
586 const splt_tags *tags_to_replace = tags;
587
588 int counter = 0;
589 const char *ptr = NULL;
590 for (ptr = word; *ptr != '\0'; ptr++)
591 {
592 if (*ptr == '@')
593 {
594 tags_to_replace = tags;
595 }
596 else if (*ptr == '#')
597 {
598 tags_to_replace = original_tags;
599 }
600
601 const char *title = tags_to_replace->title;
602 const char *artist = tags_to_replace->artist;
603 const char *album= tags_to_replace->album;
604 const char *performer = tags_to_replace->performer;
605 const char *year = tags_to_replace->year;
606 const char *comment = tags_to_replace->comment;
607 const char *genre = tags_to_replace->genre;
608 int real_track = tags_to_replace->track;
609
610 if (*ptr == '@' || *ptr == '#')
611 {
612 err = splt_su_append(&word_with_tags, buffer, counter, NULL);
613 if (err != SPLT_OK) { goto error; }
614
615 memset(buffer, '\0', 256);
616 counter = 0;
617
618 ptr++;
619
620 switch (*ptr)
621 {
622 case 's':
623 mMsShH_value = secs;
624 goto put_value;
625 case 'S':
626 mMsShH_value = next_secs;
627 goto put_value;
628 case 'm':
629 mMsShH_value = mins;
630 goto put_value;
631 case 'M':
632 mMsShH_value = next_mins;
633 goto put_value;
634 case 'h':
635 mMsShH_value = hundr;
636 goto put_value;
637 case 'H':
638 mMsShH_value = next_hundr;
639 put_value:
640 if (!eof_written)
641 {
642 if (write_eof &&
643 (*ptr == 'S' || *ptr == 'M' || *ptr == 'H'))
644 {
645 write_eof = SPLT_FALSE;
646 eof_written = SPLT_TRUE;
647
648 err = splt_su_append_str(&word_with_tags, "EOF", NULL);
649 if (err != SPLT_OK) { goto error; }
650 }
651 else if (mMsShH_value != -1)
652 {
653 char temp[6] = { '\0' };
654 temp[0] = '%';
655 temp[1] = '0';
656 char number_of_digits = '2';
657 if (*ptr == 'M' || *ptr == 'm')
658 {
659 number_of_digits = splt_of_get_number_of_digits_from_total_time(state);
660 }
661 temp[2] = number_of_digits;
662 temp[3] = 'l';
663 temp[4] = 'd';
664
665 char mMsShH_str[100] = { '\0' };
666 snprintf(mMsShH_str, 100, temp, mMsShH_value);
667
668 err = splt_su_append_str(&word_with_tags, mMsShH_str, NULL);
669 if (err != SPLT_OK) { goto error; }
670 }
671 }
672 break;
673 case 'a':
674 if (artist != NULL)
675 {
676 err = splt_su_append_str(&word_with_tags, artist, NULL);
677 if (err != SPLT_OK) { goto error; }
678 }
679 break;
680 case 'p':
681 if (performer != NULL)
682 {
683 err = splt_su_append_str(&word_with_tags, performer, NULL);
684 if (err != SPLT_OK) { goto error; }
685 }
686 break;
687 case 'b':
688 if (album != NULL)
689 {
690 err = splt_su_append_str(&word_with_tags, album, NULL);
691 if (err != SPLT_OK) { goto error; }
692 }
693 break;
694 case 't':
695 if (title != NULL)
696 {
697 err = splt_su_append_str(&word_with_tags, title, NULL);
698 if (err != SPLT_OK) { goto error; }
699 }
700 break;
701 case 'c':
702 if (comment != NULL)
703 {
704 err = splt_su_append_str(&word_with_tags, comment, NULL);
705 if (err != SPLT_OK) { goto error; }
706 }
707 break;
708 case 'g':
709 if (genre != NULL)
710 {
711 err = splt_su_append_str(&word_with_tags, genre, NULL);
712 if (err != SPLT_OK) { goto error; }
713 }
714 break;
715 case 'y':
716 if (year != NULL)
717 {
718 err = splt_su_append(&word_with_tags, year, NULL);
719 if (err != SPLT_OK) { goto error; }
720 }
721 break;
722 case 'N':
723 case 'n':
724 ;
725 int track_to_set = track;
726
727 if (*ptr == 'n')
728 {
729 track_to_set = real_track;
730 }
731
732 char temp[5] = { '\0' };
733 temp[0] = '%';
734 temp[1] = '0';
735 temp[2] = splt_of_get_oformat_number_of_digits_as_char(state);
736 temp[3] = 'd';
737
738 char track_str[10] = { '\0' };
739 snprintf(track_str, 10, temp, track_to_set);
740
741 err = splt_su_append_str(&word_with_tags, track_str, NULL);
742 if (err != SPLT_OK) { goto error; }
743 break;
744 case '@':
745 err = splt_su_append_str(&word_with_tags, "@", NULL);
746 if (err != SPLT_OK) { goto error; }
747 break;
748 default:
749 err = splt_su_append(&word_with_tags, (ptr-1), 2, NULL);
750 if (err != SPLT_OK) { goto error; }
751 break;
752 }
753 }
754 else
755 {
756 buffer[counter] = *ptr;
757 counter++;
758
759 if (counter == 255)
760 {
761 err = splt_su_append(&word_with_tags, buffer, counter, NULL);
762 if (err != SPLT_OK) { goto error; }
763 memset(buffer, '\0', 256);
764 counter = 0;
765 }
766 }
767 }
768
769 err = splt_su_append(&word_with_tags, buffer, counter, NULL);
770 if (err != SPLT_OK) { goto error; }
771
772 return word_with_tags;
773
774 error:
775 if (word_with_tags)
776 {
777 free(word_with_tags);
778 }
779
780 *error = err;
781
782 return NULL;
783 }
784
splt_tu_free_one_tags(splt_tags ** tags)785 void splt_tu_free_one_tags(splt_tags **tags)
786 {
787 if (!tags || !*tags)
788 {
789 return;
790 }
791
792 splt_tu_free_one_tags_content(*tags);
793
794 free(*tags);
795 *tags = NULL;
796 }
797
splt_tu_free_one_tags_content(splt_tags * tags)798 void splt_tu_free_one_tags_content(splt_tags *tags)
799 {
800 if (tags)
801 {
802 if (tags->title)
803 {
804 free(tags->title);
805 tags->title = NULL;
806 }
807 if (tags->artist)
808 {
809 free(tags->artist);
810 tags->artist = NULL;
811 }
812 if (tags->album)
813 {
814 free(tags->album);
815 tags->album = NULL;
816 }
817 if (tags->performer)
818 {
819 free(tags->performer);
820 tags->performer = NULL;
821 }
822 if (tags->year)
823 {
824 free(tags->year);
825 tags->year = NULL;
826 }
827 if (tags->comment)
828 {
829 free(tags->comment);
830 tags->comment = NULL;
831 }
832 if (tags->genre)
833 {
834 free(tags->genre);
835 tags->genre = NULL;
836 }
837
838 tags->track = -1;
839 }
840 }
841
splt_tu_append_tags_to_state(splt_state * state,splt_tags * tags,int append_new_tags,int original_tags_value,int use_original_tags_set,int * error)842 void splt_tu_append_tags_to_state(splt_state *state, splt_tags *tags,
843 int append_new_tags, int original_tags_value, int use_original_tags_set, int *error)
844 {
845 int err = SPLT_OK;
846
847 if (append_new_tags)
848 {
849 int original_tags = SPLT_FALSE;
850 if (use_original_tags_set) { original_tags = tags->set_original_tags; }
851
852 err = splt_tu_append_tags(state, tags->title, tags->artist, tags->album,
853 tags->performer, tags->year, tags->comment, tags->track, tags->genre,
854 original_tags);
855 }
856 else
857 {
858 err = splt_tu_append_only_non_null_previous_tags(state, tags->title,
859 tags->artist, tags->album, tags->performer, tags->year,
860 tags->comment, tags->track, tags->genre,
861 original_tags_value);
862 }
863
864 if (err < 0) { *error = err; }
865 }
866
splt_tu_set_new_tags_where_current_tags_are_null(splt_state * state,splt_tags * current_tags,splt_tags * new_tags,int index,int * error)867 void splt_tu_set_new_tags_where_current_tags_are_null(splt_state *state,
868 splt_tags *current_tags, splt_tags *new_tags,
869 int index, int *error)
870 {
871 if (!current_tags->title)
872 {
873 splt_tu_set_tags_field(state, index, SPLT_TAGS_TITLE, new_tags->title);
874 }
875 if (!current_tags->artist)
876 {
877 splt_tu_set_tags_field(state, index, SPLT_TAGS_ARTIST, new_tags->artist);
878 }
879 if (!current_tags->album)
880 {
881 splt_tu_set_tags_field(state, index, SPLT_TAGS_ALBUM, new_tags->album);
882 }
883 if (!current_tags->performer)
884 {
885 splt_tu_set_tags_field(state, index, SPLT_TAGS_PERFORMER,
886 new_tags->performer);
887 }
888 if (!current_tags->year)
889 {
890 splt_tu_set_tags_field(state, index, SPLT_TAGS_YEAR, new_tags->year);
891 }
892 if (!current_tags->comment)
893 {
894 splt_tu_set_tags_field(state, index, SPLT_TAGS_COMMENT, new_tags->comment);
895 }
896 if (current_tags->track < 0)
897 {
898 splt_tu_set_tags_field(state, index, SPLT_TAGS_TRACK, &new_tags->track);
899 }
900 if (!current_tags->genre)
901 {
902 splt_tu_set_tags_field(state, index, SPLT_TAGS_GENRE, new_tags->genre);
903 }
904 splt_tu_set_tags_field(state, index, SPLT_TAGS_ORIGINAL, &new_tags->set_original_tags);
905 }
906
splt_tu_has_one_tag_set(splt_tags * tags)907 int splt_tu_has_one_tag_set(splt_tags *tags)
908 {
909 if (tags->title != NULL ||
910 tags->artist != NULL ||
911 tags->album != NULL ||
912 tags->performer != NULL ||
913 tags->year != NULL ||
914 tags->comment != NULL ||
915 tags->track != -1 ||
916 tags->genre != NULL)
917 {
918 return SPLT_TRUE;
919 }
920
921 return SPLT_FALSE;
922 }
923
splt_tu_copy_all_tags(splt_tags * from,splt_tags * to,int * error,int copy_original_and_version)924 static void splt_tu_copy_all_tags(splt_tags *from, splt_tags *to, int *error,
925 int copy_original_and_version)
926 {
927 if (!from)
928 {
929 return;
930 }
931
932 int err = SPLT_OK;
933
934 err = splt_tu_set_field_on_tags(to, SPLT_TAGS_TITLE, from->title);
935 if (err < 0) { goto error; }
936
937 err = splt_tu_set_field_on_tags(to, SPLT_TAGS_ARTIST, from->artist);
938 if (err < 0) { goto error; }
939
940 err = splt_tu_set_field_on_tags(to, SPLT_TAGS_ALBUM, from->album);
941 if (err < 0) { goto error; }
942
943 err = splt_tu_set_field_on_tags(to, SPLT_TAGS_YEAR, from->year);
944 if (err < 0) { goto error; }
945
946 err = splt_tu_set_field_on_tags(to, SPLT_TAGS_COMMENT, from->comment);
947 if (err < 0) { goto error; }
948
949 err = splt_tu_set_field_on_tags(to, SPLT_TAGS_PERFORMER, from->performer);
950 if (err < 0) { goto error; }
951
952 err = splt_tu_set_field_on_tags(to, SPLT_TAGS_TRACK, &from->track);
953 if (err < 0) { goto error; }
954
955 err = splt_tu_set_field_on_tags(to, SPLT_TAGS_GENRE, from->genre);
956 if (err < 0) { goto error; }
957
958 if (copy_original_and_version)
959 {
960 err = splt_tu_set_field_on_tags(to, SPLT_TAGS_ORIGINAL, &from->set_original_tags);
961 if (err < 0) { goto error; }
962
963 err = splt_tu_set_field_on_tags(to, SPLT_TAGS_VERSION, &from->tags_version);
964 if (err < 0) { goto error; }
965 }
966
967 return;
968
969 error:
970 *error = err;
971 }
972
splt_tu_copy_tags_without_original_and_version(splt_tags * from,splt_tags * to,int * error)973 static void splt_tu_copy_tags_without_original_and_version(splt_tags *from, splt_tags *to, int *error)
974 {
975 splt_tu_copy_all_tags(from, to, error, SPLT_FALSE);
976 }
977
splt_tu_copy_tags(splt_tags * from,splt_tags * to,int * error)978 void splt_tu_copy_tags(splt_tags *from, splt_tags *to, int *error)
979 {
980 splt_tu_copy_all_tags(from, to, error, SPLT_TRUE);
981 }
982
splt_tu_get_tags_to_replace_in_tags(splt_state * state)983 static splt_tags *splt_tu_get_tags_to_replace_in_tags(splt_state *state)
984 {
985 int current_tags_number = splt_t_get_current_split_file_number(state) - 1;
986
987 int remaining_tags_like_x = splt_o_get_int_option(state, SPLT_OPT_ALL_REMAINING_TAGS_LIKE_X);
988
989 int real_tags_number = 0;
990 if (state->split.tags_group)
991 {
992 real_tags_number = state->split.tags_group->real_tagsnumber;
993 }
994
995 if ((current_tags_number >= real_tags_number) &&
996 (remaining_tags_like_x != -1))
997 {
998 return splt_tu_get_tags_like_x(state);
999 }
1000
1001 return splt_tu_get_tags_at(state, current_tags_number);
1002 }
1003
splt_tu_set_tags_in_tags(splt_state * state,int current_split)1004 int splt_tu_set_tags_in_tags(splt_state *state, int current_split)
1005 {
1006 int err = SPLT_OK;
1007
1008 splt_tags *tags = splt_tu_get_tags_to_replace_in_tags(state);
1009 splt_tags *cur_tags = splt_tu_get_current_tags(state);
1010
1011 if (!tags || !cur_tags)
1012 {
1013 return err;
1014 }
1015
1016 int track = -1;
1017 if (tags->track > 0)
1018 {
1019 track = tags->track;
1020 }
1021 else if (tags->track == -2)
1022 {
1023 track = -2;
1024 }
1025 else if (splt_tu_has_one_tag_set(tags))
1026 {
1027 if (current_split != -1)
1028 {
1029 track = current_split + 1;
1030 }
1031 else
1032 {
1033 track = splt_t_get_current_split_file_number(state);
1034 }
1035 }
1036
1037 cur_tags->track = track;
1038 cur_tags->tags_version = tags->tags_version;
1039
1040 int replace_tags_in_tags = splt_o_get_int_option(state, SPLT_OPT_REPLACE_TAGS_IN_TAGS);
1041
1042 splt_tags *original_tags = splt_tu_get_original_tags_tags(state);
1043
1044 char *t = splt_tu_get_replaced_with_tags(tags->title, tags, original_tags,
1045 track, &err, replace_tags_in_tags, current_split, state);
1046 if (err != SPLT_OK) { return err; }
1047 char *y = splt_tu_get_replaced_with_tags(tags->year, tags, original_tags, track, &err, replace_tags_in_tags,
1048 current_split, state);
1049 if (err != SPLT_OK) { return err; }
1050 char *a = splt_tu_get_replaced_with_tags(tags->artist, tags, original_tags, track, &err, replace_tags_in_tags,
1051 current_split, state);
1052 if (err != SPLT_OK) { return err; }
1053 char *al = splt_tu_get_replaced_with_tags(tags->album, tags, original_tags, track, &err, replace_tags_in_tags,
1054 current_split, state);
1055 if (err != SPLT_OK) { return err; }
1056 char *c = splt_tu_get_replaced_with_tags(tags->comment, tags, original_tags, track, &err, replace_tags_in_tags,
1057 current_split, state);
1058 if (err != SPLT_OK) { return err; }
1059 char *g = splt_tu_get_replaced_with_tags(tags->genre, tags, original_tags, track, &err, replace_tags_in_tags,
1060 current_split, state);
1061 if (err != SPLT_OK) { return err; }
1062
1063 splt_su_free_replace(&cur_tags->title, t);
1064 splt_su_free_replace(&cur_tags->year, y);
1065 splt_su_free_replace(&cur_tags->artist, a);
1066 splt_su_free_replace(&cur_tags->album, al);
1067 splt_su_free_replace(&cur_tags->comment, c);
1068 splt_su_free_replace(&cur_tags->genre, g);
1069
1070 return err;
1071 }
1072
splt_tu_get_tags_at(splt_state * state,int tags_index)1073 splt_tags *splt_tu_get_tags_at(splt_state *state, int tags_index)
1074 {
1075 if (!splt_tu_tags_exists(state, tags_index))
1076 {
1077 return NULL;
1078 }
1079
1080 return &state->split.tags_group->tags[tags_index];
1081 }
1082
splt_tu_get_last_tags(splt_state * state)1083 splt_tags splt_tu_get_last_tags(splt_state *state)
1084 {
1085 return state->split.tags_group->tags[state->split.tags_group->real_tagsnumber-1];
1086 }
1087
splt_tu_get_tags_field(splt_state * state,int index,int tags_field)1088 const void *splt_tu_get_tags_field(splt_state *state, int index, int tags_field)
1089 {
1090 int real_tags_number = 0;
1091 if (state->split.tags_group)
1092 {
1093 real_tags_number = state->split.tags_group->real_tagsnumber;
1094 }
1095
1096 if ((index >= real_tags_number) || (index < 0))
1097 {
1098 splt_e_error(SPLT_IERROR_INT,__func__, index, NULL);
1099 return NULL;
1100 }
1101 else
1102 {
1103 return splt_tu_get_tags_value(&state->split.tags_group->tags[index], tags_field);
1104 }
1105
1106 return NULL;
1107 }
1108
splt_tu_get_tags_value(const splt_tags * tags,int tags_field)1109 const void *splt_tu_get_tags_value(const splt_tags *tags, int tags_field)
1110 {
1111 switch (tags_field)
1112 {
1113 case SPLT_TAGS_TITLE:
1114 return tags->title;
1115 break;
1116 case SPLT_TAGS_ARTIST:
1117 return tags->artist;
1118 break;
1119 case SPLT_TAGS_ALBUM:
1120 return tags->album;
1121 break;
1122 case SPLT_TAGS_YEAR:
1123 return tags->year;
1124 break;
1125 case SPLT_TAGS_COMMENT:
1126 return tags->comment;
1127 break;
1128 case SPLT_TAGS_PERFORMER:
1129 return tags->performer;
1130 break;
1131 case SPLT_TAGS_GENRE:
1132 return tags->genre;
1133 break;
1134 case SPLT_TAGS_TRACK:
1135 return &tags->track;
1136 break;
1137 case SPLT_TAGS_VERSION:
1138 return &tags->tags_version;
1139 break;
1140 case SPLT_TAGS_ORIGINAL:
1141 return &tags->set_original_tags;
1142 break;
1143 default:
1144 splt_e_error(SPLT_IERROR_INT, __func__, -1002, NULL);
1145 return NULL;
1146 }
1147 }
1148
splt_tu_get_tags_like_x(splt_state * state)1149 splt_tags *splt_tu_get_tags_like_x(splt_state *state)
1150 {
1151 return &state->split.tags_like_x;
1152 }
1153
splt_tu_free_tags_group(splt_tags_group ** tags_group)1154 void splt_tu_free_tags_group(splt_tags_group **tags_group)
1155 {
1156 if (!tags_group || !*tags_group)
1157 {
1158 return;
1159 }
1160
1161 int i = 0;
1162 for (i = 0; i < (*tags_group)->real_tagsnumber; i++)
1163 {
1164 splt_tu_free_one_tags_content(&(*tags_group)->tags[i]);
1165 }
1166
1167 free((*tags_group)->tags);
1168 (*tags_group)->tags = NULL;
1169
1170 free(*tags_group);
1171 *tags_group = NULL;
1172 }
1173
splt_tu_free_tags(splt_state * state)1174 void splt_tu_free_tags(splt_state *state)
1175 {
1176 splt_tu_free_tags_group(&state->split.tags_group);
1177 splt_tu_free_one_tags_content(splt_tu_get_tags_like_x(state));
1178 }
1179
splt_tu_get_current_tags(splt_state * state)1180 splt_tags *splt_tu_get_current_tags(splt_state *state)
1181 {
1182 int current_tags_number = splt_t_get_current_split_file_number(state) - 1;
1183 int remaining_tags_like_x = splt_o_get_int_option(state, SPLT_OPT_ALL_REMAINING_TAGS_LIKE_X);
1184 int real_tags_number = 0;
1185 if (state->split.tags_group)
1186 {
1187 real_tags_number = state->split.tags_group->real_tagsnumber;
1188 }
1189
1190 if ((current_tags_number >= real_tags_number) &&
1191 (remaining_tags_like_x != -1))
1192 {
1193 current_tags_number = remaining_tags_like_x;
1194 }
1195
1196 return splt_tu_get_tags_at(state, current_tags_number);
1197 }
1198
splt_tu_get_artist_or_performer_ptr(const splt_tags * tags)1199 char *splt_tu_get_artist_or_performer_ptr(const splt_tags *tags)
1200 {
1201 if (!tags)
1202 {
1203 return NULL;
1204 }
1205
1206 char *artist_or_performer = tags->artist;
1207
1208 if (tags->performer == NULL)
1209 {
1210 return artist_or_performer;
1211 }
1212
1213 if (tags->performer[0] != '\0')
1214 {
1215 return tags->performer;
1216 }
1217
1218 return artist_or_performer;
1219 }
1220
splt_tu_copy_tags_on_all_tracks(splt_state * state,int tracks,const splt_tags * all_tags)1221 int splt_tu_copy_tags_on_all_tracks(splt_state *state, int tracks, const splt_tags *all_tags)
1222 {
1223 int err = SPLT_OK;
1224
1225 const char *all_artist = splt_tu_get_tags_value(all_tags, SPLT_TAGS_ARTIST);
1226 const char *all_album = splt_tu_get_tags_value(all_tags, SPLT_TAGS_ALBUM);
1227 const char *all_year = splt_tu_get_tags_value(all_tags, SPLT_TAGS_YEAR);
1228 const char *all_genre = splt_tu_get_tags_value(all_tags, SPLT_TAGS_GENRE);
1229 const char *all_title = splt_tu_get_tags_value(all_tags, SPLT_TAGS_TITLE);
1230 const char *all_comment = splt_tu_get_tags_value(all_tags, SPLT_TAGS_COMMENT);
1231
1232 int i = 0;
1233 for (i = 0; i < tracks;i++)
1234 {
1235 if (all_artist != NULL)
1236 {
1237 if (!splt_tu_tags_exists(state, i) ||
1238 splt_tu_get_tags_field(state, i, SPLT_TAGS_ARTIST) == NULL)
1239 {
1240 err = splt_tu_set_tags_field(state, i, SPLT_TAGS_ARTIST, all_artist);
1241 if (err != SPLT_OK) { break; }
1242 }
1243 }
1244
1245 if (all_album != NULL)
1246 {
1247 if (!splt_tu_tags_exists(state, i) ||
1248 splt_tu_get_tags_field(state, i, SPLT_TAGS_ALBUM) == NULL)
1249 {
1250 err = splt_tu_set_tags_field(state, i, SPLT_TAGS_ALBUM, all_album);
1251 if (err != SPLT_OK) { break; }
1252 }
1253 }
1254
1255 if (all_year != NULL)
1256 {
1257 if (!splt_tu_tags_exists(state, i) ||
1258 splt_tu_get_tags_field(state, i, SPLT_TAGS_YEAR) == NULL)
1259 {
1260 err = splt_tu_set_tags_field(state, i, SPLT_TAGS_YEAR, all_year);
1261 if (err != SPLT_OK) { break; }
1262 }
1263 }
1264
1265 if (all_genre != NULL)
1266 {
1267 if (!splt_tu_tags_exists(state, i) ||
1268 splt_tu_get_tags_field(state, i, SPLT_TAGS_GENRE) == NULL)
1269 {
1270 err = splt_tu_set_tags_field(state, i, SPLT_TAGS_GENRE, all_genre);
1271 if (err != SPLT_OK) { break; }
1272 }
1273 }
1274
1275 if (all_title != NULL)
1276 {
1277 if (!splt_tu_tags_exists(state, i) ||
1278 splt_tu_get_tags_field(state, i, SPLT_TAGS_TITLE) == NULL)
1279 {
1280 err = splt_tu_set_tags_field(state, i, SPLT_TAGS_TITLE, all_title);
1281 if (err != SPLT_OK) { break; }
1282 }
1283 }
1284
1285 if (all_comment != NULL)
1286 {
1287 if (!splt_tu_tags_exists(state, i) ||
1288 splt_tu_get_tags_field(state, i, SPLT_TAGS_COMMENT) == NULL)
1289 {
1290 err = splt_tu_set_tags_field(state, i, SPLT_TAGS_COMMENT, all_comment);
1291 if (err != SPLT_OK) { break; }
1292 }
1293 }
1294 }
1295
1296 return err;
1297 }
1298
splt_tu_set_field_on_tags(splt_tags * tags,int tags_field,const void * data)1299 int splt_tu_set_field_on_tags(splt_tags *tags, int tags_field, const void *data)
1300 {
1301 int err = SPLT_OK;
1302
1303 switch (tags_field)
1304 {
1305 case SPLT_TAGS_TITLE:
1306 err = splt_su_copy((char *)data, &tags->title);
1307 break;
1308 case SPLT_TAGS_ARTIST:
1309 err = splt_su_copy((char *)data, &tags->artist);
1310 break;
1311 case SPLT_TAGS_ALBUM:
1312 err = splt_su_copy((char *)data, &tags->album);
1313 break;
1314 case SPLT_TAGS_YEAR:
1315 err = splt_su_copy((char *)data, &tags->year);
1316 break;
1317 case SPLT_TAGS_COMMENT:
1318 err = splt_su_copy((char *)data, &tags->comment);
1319 break;
1320 case SPLT_TAGS_PERFORMER:
1321 err = splt_su_copy((char *)data, &tags->performer);
1322 break;
1323 case SPLT_TAGS_TRACK:
1324 tags->track = *((int *)data);
1325 break;
1326 case SPLT_TAGS_GENRE:
1327 err = splt_su_copy((char *)data, &tags->genre);
1328 break;
1329 case SPLT_TAGS_VERSION:
1330 tags->tags_version = *((int *)data);
1331 break;
1332 case SPLT_TAGS_ORIGINAL:
1333 tags->set_original_tags = *((int *)data);
1334 break;
1335 default:
1336 splt_e_error(SPLT_IERROR_INT,__func__, -500, NULL);
1337 break;
1338 }
1339
1340 return err;
1341 }
1342
splt_tu_remove_tags_of_skippoints(splt_state * state)1343 splt_code splt_tu_remove_tags_of_skippoints(splt_state *state)
1344 {
1345 splt_code error = SPLT_OK;
1346
1347 int number;
1348 splt_tags *tags = splt_tu_duplicate_tags(state, &error, &number);
1349 if (error < 0 || tags == NULL) { return error; }
1350
1351 splt_tu_free_tags_group(&state->split.tags_group);
1352
1353 int splitpoints_number = state->split.points->real_splitnumber;
1354 int i = 0;
1355 for (i = 0;i < splitpoints_number;i++)
1356 {
1357 if (i >= number) { continue; }
1358
1359 if (splt_sp_get_splitpoint_type(state, i, &error) != SPLT_SKIPPOINT)
1360 {
1361 splt_tu_append_tags_to_state(state, &tags[i], SPLT_TRUE, SPLT_FALSE, SPLT_TRUE, &error);
1362 }
1363 if (error < 0) { goto end; }
1364 }
1365
1366 end:
1367 for (i = 0;i < number;i++)
1368 {
1369 splt_tu_free_one_tags_content(&tags[i]);
1370 }
1371 free(tags);
1372
1373 return error;
1374 }
1375
1376