libmp3splt
src/tags_utils.c
00001 /**********************************************************
00002  * libmp3splt -- library based on mp3splt,
00003  *               for mp3/ogg splitting without decoding
00004  *
00005  * Copyright (c) 2002-2005 M. Trotta - <mtrotta@users.sourceforge.net>
00006  * Copyright (c) 2005-2011 Alexandru Munteanu - io_fx@yahoo.fr
00007  *
00008  *********************************************************/
00009 
00010 /**********************************************************
00011  * This program is free software; you can redistribute it and/or
00012  * modify it under the terms of the GNU General Public License
00013  * as published by the Free Software Foundation; either version 2
00014  * of the License, or (at your option) any later version.
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU General Public License
00022  * along with this program; if not, write to the Free Software
00023  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
00024  * 02111-1307,
00025  * USA.
00026  *********************************************************/
00027 
00028 #include <string.h>
00029 
00030 #include "splt.h"
00031 #include "tags_utils.h"
00032 
00033 void splt_tu_free_original_tags(splt_state *state)
00034 {
00035   if (state->original_tags.year)
00036   {
00037     free(state->original_tags.year);
00038     state->original_tags.year = NULL;
00039   }
00040   if (state->original_tags.artist)
00041   {
00042     free(state->original_tags.artist);
00043     state->original_tags.artist = NULL;
00044   }
00045   if (state->original_tags.album)
00046   {
00047     free(state->original_tags.album);
00048     state->original_tags.album = NULL;
00049   }
00050   if (state->original_tags.title)
00051   {
00052     free(state->original_tags.title);
00053     state->original_tags.title = NULL;
00054   }
00055   if (state->original_tags.comment)
00056   {
00057     free(state->original_tags.comment);
00058     state->original_tags.comment = NULL;
00059   }
00060   if (state->original_tags.genre)
00061   {
00062     free(state->original_tags.genre);
00063     state->original_tags.genre = NULL;
00064   }
00065   state->original_tags.track = -1;
00066 }
00067 
00069 splt_tags *splt_tu_get_tags(splt_state *state, int *tags_number)
00070 {
00071   *tags_number = state->split.real_tagsnumber;
00072   return state->split.tags;
00073 }
00074 
00075 void splt_tu_auto_increment_tracknumber(splt_state *state)
00076 {
00077   int current_split = splt_t_get_current_split_file_number(state) - 1;
00078   int old_current_split = current_split;
00079 
00080   int remaining_tags_like_x = splt_o_get_int_option(state, SPLT_OPT_ALL_REMAINING_TAGS_LIKE_X); 
00081   if (remaining_tags_like_x != -1)
00082   {
00083     if (current_split >= state->split.real_tagsnumber)
00084     {
00085       current_split = remaining_tags_like_x;
00086     }
00087 
00088     if (splt_o_get_int_option(state, SPLT_OPT_AUTO_INCREMENT_TRACKNUMBER_TAGS) > 0)
00089     {
00090       if (current_split == remaining_tags_like_x)
00091       {
00092         if ((old_current_split > 0) && 
00093             (old_current_split-1 < state->split.real_tagsnumber) && 
00094             (old_current_split != remaining_tags_like_x))
00095         {
00096           int *prev_track = (int *)splt_tu_get_tags_field(state, old_current_split - 1, SPLT_TAGS_TRACK);
00097           int previous_track = 0;
00098           if (prev_track != NULL)
00099           {
00100             previous_track = *prev_track;
00101           }
00102           splt_tu_set_tags_field(state, remaining_tags_like_x, SPLT_TAGS_TRACK, &previous_track);
00103         }
00104 
00105         if (old_current_split != current_split)
00106         {
00107           int tracknumber = 1;
00108           if (splt_tu_tags_exists(state, current_split))
00109           {
00110             int *track = (int *)splt_tu_get_tags_field(state, current_split, SPLT_TAGS_TRACK);
00111             if (track != NULL)
00112             {
00113               tracknumber = *track;
00114             }
00115           }
00116           int new_tracknumber = tracknumber + 1;
00117           splt_tu_set_tags_field(state, current_split, SPLT_TAGS_TRACK, &new_tracknumber);
00118           splt_tu_set_like_x_tags_field(state, SPLT_TAGS_TRACK, &new_tracknumber);
00119         }
00120       }
00121     }
00122   }
00123 }
00124 
00125 void splt_tu_get_original_tags(splt_state *state, int *err)
00126 {
00127   if (! splt_io_input_is_stdin(state))
00128   {
00129     splt_tu_free_original_tags(state);
00130     splt_p_set_original_tags(state, err);
00131   }
00132 }
00133 
00134 int splt_tu_append_tags(splt_state *state, 
00135     const char *title, const char *artist,
00136     const char *album, const char *performer,
00137     const char *year, const char *comment,
00138     int track, const char *genre)
00139 {
00140   int error = SPLT_OK;
00141   int old_tagsnumber = state->split.real_tagsnumber;
00142 
00143   error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_TITLE, title);
00144   if (error != SPLT_OK)
00145     return error;
00146 
00147   error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_ARTIST, artist);
00148   if (error != SPLT_OK)
00149     return error;
00150 
00151   error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_ALBUM, album);
00152   if (error != SPLT_OK)
00153     return error;
00154 
00155   error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_PERFORMER, performer);
00156   if (error != SPLT_OK)
00157     return error;
00158 
00159   error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_YEAR, year);
00160   if (error != SPLT_OK)
00161     return error;
00162 
00163   error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_COMMENT, comment);
00164   if (error != SPLT_OK)
00165     return error;
00166 
00167   error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_TRACK, &track);
00168   if (error != SPLT_OK)
00169     return error;
00170 
00171   error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_GENRE, genre);
00172   return error;
00173 }
00174 
00175 int splt_tu_append_original_tags(splt_state *state)
00176 {
00177   int err = SPLT_OK;
00178 
00179   char *new_title = NULL;
00180   char *new_artist = NULL;
00181   char *new_album = NULL;
00182   char *new_year = NULL;
00183   char *new_comment = NULL;
00184   char *new_genre = NULL;
00185 
00186   new_title = splt_su_replace_all(state->original_tags.title, "@", "@@", &err);
00187   if (err != SPLT_OK) { goto end; }
00188 
00189   new_artist = splt_su_replace_all(state->original_tags.artist, "@", "@@", &err);
00190   if (err != SPLT_OK) { goto end; }
00191 
00192   new_album = splt_su_replace_all(state->original_tags.album, "@", "@@", &err);
00193   if (err != SPLT_OK) { goto end; }
00194 
00195   new_year = splt_su_replace_all(state->original_tags.year, "@", "@@", &err);
00196   if (err != SPLT_OK) { goto end; }
00197 
00198   new_comment = splt_su_replace_all(state->original_tags.comment, "@", "@@", &err);
00199   if (err != SPLT_OK) { goto end; }
00200 
00201   new_genre = splt_su_replace_all(state->original_tags.genre, "@", "@@", &err);
00202   if (err != SPLT_OK) { goto end; }
00203 
00204   err = splt_tu_append_tags(state, new_title, new_artist, new_album, NULL,
00205       new_year, new_comment, state->original_tags.track, new_genre);
00206 
00207 end:
00208   if (new_title) { free(new_title); }
00209   if (new_artist) { free(new_artist); }
00210   if (new_album) { free(new_album); }
00211   if (new_year) { free(new_year); }
00212   if (new_comment) { free(new_comment); }
00213   if (new_genre) { free(new_genre); }
00214 
00215   return err;
00216 }
00217 
00218 int splt_tu_append_only_non_null_previous_tags(splt_state *state, 
00219     const char *title, const char *artist,
00220     const char *album, const char *performer,
00221     const char *year, const char *comment,
00222     int track, const char *genre)
00223 {
00224   int error = SPLT_OK;
00225   int old_tagsnumber = state->split.real_tagsnumber-1;
00226 
00227   if (old_tagsnumber >= 0)
00228   {
00229     if (title != NULL)
00230     {
00231       error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_TITLE, title);
00232     }
00233     if (error != SPLT_OK)
00234       return error;
00235 
00236     if (artist != NULL)
00237     {
00238       error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_ARTIST, artist);
00239     }
00240     if (error != SPLT_OK)
00241       return error;
00242 
00243     if (album != NULL)
00244     {
00245       error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_ALBUM, album);
00246     }
00247     if (error != SPLT_OK)
00248       return error;
00249 
00250     if (performer != NULL)
00251     {
00252       error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_PERFORMER, performer);
00253     }
00254     if (error != SPLT_OK)
00255       return error;
00256 
00257     if (year != NULL)
00258     {
00259       error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_YEAR, year);
00260     }
00261     if (error != SPLT_OK)
00262       return error;
00263 
00264     if (comment != NULL)
00265     {
00266       error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_COMMENT, comment);
00267     }
00268     if (error != SPLT_OK)
00269       return error;
00270 
00271     if (track != -1)
00272     {
00273       error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_TRACK, &track);
00274     }
00275     if (error != SPLT_OK)
00276       return error;
00277 
00278     if (genre != NULL)
00279     {
00280       error = splt_tu_set_tags_field(state, old_tagsnumber, SPLT_TAGS_GENRE, genre);
00281     }
00282   }
00283 
00284   return error;
00285 }
00286 
00287 void splt_tu_reset_tags(splt_tags *tags)
00288 {
00289   tags->title = NULL;
00290   tags->artist = NULL;
00291   tags->album = NULL;
00292   tags->performer = NULL;
00293   tags->year = NULL;
00294   tags->comment = NULL;
00295   tags->track = -1;
00296   tags->genre = NULL;
00297   tags->tags_version = 0;
00298 }
00299 
00300 splt_tags *splt_tu_new_tags(splt_state *state, int *error)
00301 {
00302   splt_tags *tags = malloc(sizeof(splt_tags));
00303 
00304   if (tags == NULL)
00305   {
00306     *error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
00307     return NULL;
00308   }
00309 
00310   memset(tags, sizeof(splt_tags), '\0');
00311 
00312   splt_tu_reset_tags(tags);
00313 
00314   return tags;
00315 }
00316 
00317 static void splt_tu_set_empty_tags(splt_state *state, int index)
00318 {
00319   splt_tu_reset_tags(&state->split.tags[index]);
00320 }
00321 
00322 int splt_tu_new_tags_if_necessary(splt_state *state, int index)
00323 {
00324   int error = SPLT_OK;
00325 
00326   if (!state->split.tags)
00327   {
00328     if ((index > state->split.real_tagsnumber) || (index < 0))
00329     {
00330       splt_e_error(SPLT_IERROR_INT,__func__, index, NULL);
00331     }
00332     else
00333     {
00334       state->split.tags = splt_tu_new_tags(state, &error);
00335       if (error < 0)
00336       {
00337         return error;
00338       }
00339       else
00340       {
00341         splt_tu_set_empty_tags(state, index);
00342         state->split.real_tagsnumber++;
00343       }
00344     }
00345   }
00346   else
00347   {
00348     if ((index > state->split.real_tagsnumber) || (index < 0))
00349     {
00350       splt_e_error(SPLT_IERROR_INT,__func__, index, NULL);
00351     }
00352     else
00353     {
00354       if (index == state->split.real_tagsnumber)
00355       {
00356         if ((state->split.tags = realloc(state->split.tags,
00357                 sizeof(splt_tags) * (index+1))) == NULL)
00358         {
00359           error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
00360           return error;
00361         }
00362         else
00363         {
00364           splt_tu_set_empty_tags(state,index);
00365           state->split.real_tagsnumber++;
00366         }
00367       }
00368     }
00369   }
00370 
00371   return error;
00372 }
00373 
00374 int splt_tu_tags_exists(splt_state *state, int index)
00375 {
00376   if ((index >= 0) && (index < state->split.real_tagsnumber))
00377   {
00378     return SPLT_TRUE;
00379   }
00380   else
00381   {
00382     return SPLT_FALSE;
00383   }
00384 }
00385 
00386 int splt_tu_set_tags_field(splt_state *state, int index,
00387     int tags_field, const void *data)
00388 {
00389   int error = SPLT_OK;
00390 
00391   error = splt_tu_new_tags_if_necessary(state,index);
00392   if (error != SPLT_OK) { return error; }
00393 
00394   if ((index >= state->split.real_tagsnumber) || (index < 0))
00395   {
00396     error = SPLT_ERROR_INEXISTENT_SPLITPOINT;
00397     splt_e_error(SPLT_IERROR_INT,__func__, index, NULL);
00398     return error;
00399   }
00400   else
00401   {
00402     splt_tu_set_field_on_tags(&state->split.tags[index], tags_field, data);
00403   }
00404 
00405   if (error != SPLT_OK)
00406   {
00407     splt_e_error(SPLT_IERROR_INT,__func__, index, NULL);
00408   }
00409 
00410   return error;
00411 }
00412 
00413 int splt_tu_set_like_x_tags_field(splt_state *state, int tags_field, const void *data)
00414 {
00415   return splt_tu_set_field_on_tags(&state->split.tags_like_x, tags_field, data);
00416 }
00417 
00418 int splt_tu_set_original_tags_field(splt_state *state, int tags_field, const void *data)
00419 {
00420   return splt_tu_set_field_on_tags(&state->original_tags, tags_field, data);
00421 }
00422 
00423 static char *splt_tu_get_replaced_with_tags(const char *word,
00424     const splt_tags *tags, int track, int *error, int replace_tags_in_tags)
00425 {
00426   int err = SPLT_OK;
00427 
00428   char *word_with_tags = NULL;
00429 
00430   if (!replace_tags_in_tags)
00431   {
00432     err = splt_su_copy(word, &word_with_tags);
00433     if (err < 0) { *error = err; }
00434     return word_with_tags;
00435   }
00436 
00437   char buffer[256] = { '\0' };
00438 
00439   if (word == NULL)
00440   {
00441     return NULL;
00442   }
00443 
00444   const char *title = tags->title;
00445   const char *artist = tags->artist;
00446   const char *album= tags->album;
00447   const char *performer = tags->performer;
00448   const char *year = tags->year;
00449   const char *comment = tags->comment;
00450 
00451   int counter = 0;
00452   const char *ptr = NULL;
00453   for (ptr = word; *ptr != '\0'; ptr++)
00454   {
00455     if (*ptr == '@')
00456     {
00457       err = splt_su_append(&word_with_tags, buffer, counter, NULL);
00458       if (err != SPLT_OK) { goto error; }
00459 
00460       memset(buffer, 256, '\0');
00461       counter = 0;
00462 
00463       ptr++;
00464 
00465       switch (*ptr)
00466       {
00467         case 'a':
00468           if (artist != NULL)
00469           {
00470             err = splt_su_append_str(&word_with_tags, artist, NULL);
00471             if (err != SPLT_OK) { goto error; }
00472           }
00473           break;
00474         case 'p':
00475           if (performer != NULL)
00476           {
00477             err = splt_su_append_str(&word_with_tags, performer, NULL);
00478             if (err != SPLT_OK) { goto error; }
00479           }
00480           break;
00481         case 'b':
00482           if (album != NULL)
00483           {
00484             err = splt_su_append_str(&word_with_tags, album, NULL);
00485             if (err != SPLT_OK) { goto error; }
00486           }
00487           break;
00488         case 't':
00489           if (title != NULL)
00490           {
00491             err = splt_su_append_str(&word_with_tags, title, NULL);
00492             if (err != SPLT_OK) { goto error; }
00493           }
00494           break;
00495         case 'c':
00496           if (comment != NULL)
00497           {
00498             err = splt_su_append_str(&word_with_tags, comment, NULL);
00499             if (err != SPLT_OK) { goto error; }
00500           }
00501           break;
00502         case 'y':
00503           if (year != NULL)
00504           {
00505             err = splt_su_append(&word_with_tags, year, NULL);
00506             if (err != SPLT_OK) { goto error; }
00507           }
00508           break;
00509         case 'N':
00510         case 'n':
00511           ;
00512           char track_str[10] = { '\0' };
00513           snprintf(track_str, 10, "%d",track);
00514           err = splt_su_append_str(&word_with_tags, track_str, NULL);
00515           if (err != SPLT_OK) { goto error; }
00516           break;
00517         case '@':
00518           err = splt_su_append_str(&word_with_tags, "@", NULL);
00519           if (err != SPLT_OK) { goto error; }
00520           break;
00521         default:
00522           err = splt_su_append(&word_with_tags, (ptr-1), 2, NULL);
00523           if (err != SPLT_OK) { goto error; }
00524           break;
00525       }
00526     }
00527     else
00528     {
00529       buffer[counter] = *ptr;
00530       counter++;
00531 
00532       if (counter == 255)
00533       {
00534         err = splt_su_append(&word_with_tags, buffer, counter, NULL);
00535         if (err != SPLT_OK) { goto error; }
00536         memset(buffer, 256, '\0');
00537         counter = 0;
00538       }
00539     }
00540   }
00541 
00542   err = splt_su_append(&word_with_tags, buffer, counter, NULL);
00543   if (err != SPLT_OK) { goto error; }
00544 
00545   return word_with_tags;
00546 
00547 error:
00548   if (word_with_tags)
00549   {
00550     free(word_with_tags);
00551   }
00552 
00553   *error = err;
00554 
00555   return NULL;
00556 }
00557 
00558 void splt_tu_free_one_tags(splt_tags **tags)
00559 {
00560   if (!tags || !*tags)
00561   {
00562     return;
00563   }
00564 
00565   splt_tu_free_one_tags_content(*tags);
00566 
00567   free(*tags);
00568   *tags = NULL;
00569 }
00570 
00571 void splt_tu_free_one_tags_content(splt_tags *tags)
00572 {
00573   if (tags)
00574   {
00575     if (tags->title)
00576     {
00577       free(tags->title);
00578       tags->title = NULL;
00579     }
00580     if (tags->artist)
00581     {
00582       free(tags->artist);
00583       tags->artist = NULL;
00584     }
00585     if (tags->album)
00586     {
00587       free(tags->album);
00588       tags->album = NULL;
00589     }
00590     if (tags->performer)
00591     {
00592       free(tags->performer);
00593       tags->performer = NULL;
00594     }
00595     if (tags->year)
00596     {
00597       free(tags->year);
00598       tags->year = NULL;
00599     }
00600     if (tags->comment)
00601     {
00602       free(tags->comment);
00603       tags->comment = NULL;
00604     }
00605     if (tags->genre)
00606     {
00607       free(tags->genre);
00608       tags->genre = NULL;
00609     }
00610 
00611     tags->track = -1;
00612   }
00613 }
00614 
00615 void splt_tu_append_tags_to_state(splt_state *state, splt_tags *tags, 
00616     int append_new_tags, int *error)
00617 {
00618   int err = SPLT_OK;
00619 
00620   if (append_new_tags)
00621   {
00622     err = splt_tu_append_tags(state, tags->title, tags->artist, tags->album,
00623         tags->performer, tags->year, tags->comment, tags->track, tags->genre);
00624   }
00625   else
00626   {
00627     err = splt_tu_append_only_non_null_previous_tags(state, tags->title,
00628         tags->artist, tags->album, tags->performer, tags->year, 
00629         tags->comment, tags->track, tags->genre);
00630   }
00631 
00632   if (err < 0)
00633   {
00634     *error = err;
00635   }
00636 }
00637 
00638 void splt_tu_set_new_tags_where_current_tags_are_null(splt_state *state,
00639     splt_tags *current_tags, splt_tags *new_tags, 
00640     int index, int *error)
00641 {
00642   if (!current_tags->title)
00643   {
00644     splt_tu_set_tags_field(state, index, SPLT_TAGS_TITLE, new_tags->title);
00645   }
00646   if (!current_tags->artist)
00647   {
00648     splt_tu_set_tags_field(state, index, SPLT_TAGS_ARTIST, new_tags->artist);
00649   }
00650   if (!current_tags->album)
00651   {
00652     splt_tu_set_tags_field(state, index, SPLT_TAGS_ALBUM, new_tags->album);
00653   }
00654   if (!current_tags->performer)
00655   {
00656     splt_tu_set_tags_field(state, index, SPLT_TAGS_PERFORMER,
00657         new_tags->performer);
00658   }
00659   if (!current_tags->year)
00660   {
00661     splt_tu_set_tags_field(state, index, SPLT_TAGS_YEAR, new_tags->year);
00662   }
00663   if (!current_tags->comment)
00664   {
00665     splt_tu_set_tags_field(state, index, SPLT_TAGS_COMMENT, new_tags->comment);
00666   }
00667   if (current_tags->track < 0)
00668   {
00669     splt_tu_set_tags_field(state, index, SPLT_TAGS_TRACK, &new_tags->track);
00670   }
00671   if (!current_tags->genre)
00672   {
00673     splt_tu_set_tags_field(state, index, SPLT_TAGS_GENRE, new_tags->genre);
00674   }
00675 }
00676 
00677 int splt_tu_has_one_tag_set(splt_tags *tags)
00678 {
00679   if (tags->title != NULL ||
00680       tags->artist != NULL ||
00681       tags->album != NULL ||
00682       tags->performer != NULL ||
00683       tags->year != NULL ||
00684       tags->comment != NULL ||
00685       tags->track != -1 ||
00686       tags->genre != NULL)
00687   {
00688     return SPLT_TRUE;
00689   }
00690 
00691   return SPLT_FALSE;
00692 }
00693 
00694 void splt_tu_copy_tags(splt_tags *from, splt_tags *to, int *error)
00695 {
00696   int err = SPLT_OK;
00697 
00698   err = splt_tu_set_field_on_tags(to, SPLT_TAGS_TITLE, from->title);
00699   if (err < 0) { goto error; }
00700 
00701   err = splt_tu_set_field_on_tags(to, SPLT_TAGS_ARTIST, from->artist);
00702   if (err < 0) { goto error; }
00703 
00704   err = splt_tu_set_field_on_tags(to, SPLT_TAGS_ALBUM, from->album);
00705   if (err < 0) { goto error; }
00706 
00707   err = splt_tu_set_field_on_tags(to, SPLT_TAGS_YEAR, from->year);
00708   if (err < 0) { goto error; }
00709 
00710   err = splt_tu_set_field_on_tags(to, SPLT_TAGS_COMMENT, from->comment);
00711   if (err < 0) { goto error; }
00712 
00713   err = splt_tu_set_field_on_tags(to, SPLT_TAGS_PERFORMER, from->performer);
00714   if (err < 0) { goto error; }
00715 
00716   err = splt_tu_set_field_on_tags(to, SPLT_TAGS_TRACK, &from->track);
00717   if (err < 0) { goto error; }
00718 
00719   err = splt_tu_set_field_on_tags(to, SPLT_TAGS_GENRE, from->genre);
00720   if (err < 0) { goto error; }
00721 
00722   err = splt_tu_set_field_on_tags(to, SPLT_TAGS_VERSION, &from->tags_version);
00723   if (err < 0) { goto error; }
00724 
00725   return;
00726 
00727 error:
00728   *error = err;
00729 }
00730 
00731 static splt_tags *splt_tu_get_tags_to_replace_in_tags(splt_state *state)
00732 {
00733   int current_tags_number = splt_t_get_current_split_file_number(state) - 1;
00734 
00735   int remaining_tags_like_x = splt_o_get_int_option(state, SPLT_OPT_ALL_REMAINING_TAGS_LIKE_X); 
00736 
00737   if ((current_tags_number >= state->split.real_tagsnumber) &&
00738       (remaining_tags_like_x != -1))
00739   {
00740     return splt_tu_get_tags_like_x(state);
00741   }
00742 
00743   return splt_tu_get_tags_at(state, current_tags_number);
00744 }
00745 
00746 int splt_tu_set_tags_in_tags(splt_state *state, int current_split)
00747 {
00748   int err = SPLT_OK;
00749 
00750   splt_tags *tags = splt_tu_get_tags_to_replace_in_tags(state);
00751   splt_tags *cur_tags = splt_tu_get_current_tags(state);
00752 
00753   if (!tags || !cur_tags)
00754   {
00755     return err;
00756   }
00757 
00758   int track = -1;
00759   if (tags->track > 0)
00760   {
00761     track = tags->track;
00762   }
00763   else if (splt_tu_has_one_tag_set(tags))
00764   {
00765     if (current_split != -1)
00766     {
00767       track = current_split + 1;
00768     }
00769     else
00770     {
00771       track = splt_t_get_current_split_file_number(state);
00772     }
00773   }
00774 
00775   cur_tags->track = track;
00776   cur_tags->tags_version = tags->tags_version;
00777 
00778   int replace_tags_in_tags = splt_o_get_int_option(state, SPLT_OPT_REPLACE_TAGS_IN_TAGS);
00779 
00780   char *t = splt_tu_get_replaced_with_tags(tags->title, tags, track, &err, replace_tags_in_tags);
00781   if (err != SPLT_OK) { return err; }
00782   char *y = splt_tu_get_replaced_with_tags(tags->year, tags, track, &err, replace_tags_in_tags);
00783   if (err != SPLT_OK) { return err; }
00784   char *a = splt_tu_get_replaced_with_tags(tags->artist, tags, track, &err, replace_tags_in_tags);
00785   if (err != SPLT_OK) { return err; }
00786   char *al = splt_tu_get_replaced_with_tags(tags->album, tags, track, &err, replace_tags_in_tags);
00787   if (err != SPLT_OK) { return err; }
00788   char *c = splt_tu_get_replaced_with_tags(tags->comment, tags, track, &err, replace_tags_in_tags);
00789   if (err != SPLT_OK) { return err; }
00790   char *g = splt_tu_get_replaced_with_tags(tags->genre, tags, track, &err, replace_tags_in_tags);
00791   if (err != SPLT_OK) { return err; }
00792 
00793   splt_su_free_replace(&cur_tags->title, t);
00794   splt_su_free_replace(&cur_tags->year, y);
00795   splt_su_free_replace(&cur_tags->artist, a);
00796   splt_su_free_replace(&cur_tags->album, al);
00797   splt_su_free_replace(&cur_tags->comment, c);
00798   splt_su_free_replace(&cur_tags->genre, g);
00799 
00800   return err;
00801 }
00802 
00803 splt_tags *splt_tu_get_tags_at(splt_state *state, int tags_index)
00804 {
00805   if (!splt_tu_tags_exists(state, tags_index))
00806   {
00807     return NULL;
00808   }
00809 
00810   return &state->split.tags[tags_index];
00811 }
00812 
00813 splt_tags splt_tu_get_last_tags(splt_state *state)
00814 {
00815   return state->split.tags[state->split.real_tagsnumber-1];
00816 }
00817 
00818 void *splt_tu_get_tags_field(splt_state *state, int index, int tags_field)
00819 {
00820   if ((index >= state->split.real_tagsnumber) || (index < 0))
00821   {
00822     splt_e_error(SPLT_IERROR_INT,__func__, index, NULL);
00823     return NULL;
00824   }
00825   else
00826   {
00827     switch(tags_field)
00828     {
00829       case SPLT_TAGS_TITLE:
00830         return state->split.tags[index].title;
00831         break;
00832       case SPLT_TAGS_ARTIST:
00833         return state->split.tags[index].artist;
00834         break;
00835       case SPLT_TAGS_ALBUM:
00836         return state->split.tags[index].album;
00837         break;
00838       case SPLT_TAGS_YEAR:
00839         return state->split.tags[index].year;
00840         break;
00841       case SPLT_TAGS_COMMENT:
00842         return state->split.tags[index].comment;
00843         break;
00844       case SPLT_TAGS_PERFORMER:
00845         return state->split.tags[index].performer;
00846         break;
00847       case SPLT_TAGS_TRACK:
00848         return &state->split.tags[index].track;
00849         break;
00850       case SPLT_TAGS_VERSION:
00851         return &state->split.tags[index].tags_version;
00852         break;
00853       case SPLT_TAGS_GENRE:
00854         return state->split.tags[index].genre;
00855         break;
00856       default:
00857         splt_e_error(SPLT_IERROR_INT,__func__, index, NULL);
00858         return NULL;
00859     }
00860   }
00861 
00862   return NULL;
00863 }
00864 
00865 splt_tags *splt_tu_get_tags_like_x(splt_state *state)
00866 {
00867   return &state->split.tags_like_x;
00868 }
00869 
00870 void splt_tu_free_tags(splt_state *state)
00871 {
00872   if (state->split.tags)
00873   {
00874     int i = 0;
00875     for (i = 0; i < state->split.real_tagsnumber; i++)
00876     {
00877       splt_tu_free_one_tags_content(&state->split.tags[i]);
00878     }
00879     free(state->split.tags);
00880     state->split.tags = NULL;
00881   }
00882 
00883   state->split.real_tagsnumber = 0;
00884 
00885   splt_tu_free_one_tags_content(splt_tu_get_tags_like_x(state));
00886 }
00887 
00888 splt_tags *splt_tu_get_current_tags(splt_state *state)
00889 {
00890   int current_tags_number = splt_t_get_current_split_file_number(state) - 1;
00891 
00892   int remaining_tags_like_x = splt_o_get_int_option(state, SPLT_OPT_ALL_REMAINING_TAGS_LIKE_X); 
00893   if ((current_tags_number >= state->split.real_tagsnumber) &&
00894       (remaining_tags_like_x != -1))
00895   {
00896     current_tags_number = remaining_tags_like_x; 
00897   }
00898 
00899   return splt_tu_get_tags_at(state, current_tags_number);
00900 }
00901 
00902 char *splt_tu_get_artist_or_performer_ptr(splt_tags *tags)
00903 {
00904   if (!tags)
00905   {
00906     return NULL;
00907   }
00908 
00909   char *artist_or_performer = tags->artist;
00910 
00911   if (tags->performer == NULL)
00912   {
00913     return artist_or_performer;
00914   }
00915 
00916   if (tags->performer[0] != '\0')
00917   {
00918     return tags->performer;
00919   }
00920 
00921   return artist_or_performer;
00922 }
00923 
00924 int splt_tu_copy_first_common_tags_on_all_tracks(splt_state *state, int tracks)
00925 {
00926   int err = SPLT_OK;
00927 
00928   char *artist0 = NULL;
00929   char *album0 = NULL;
00930   char *year0 = NULL;
00931   char *genre0 = NULL;
00932 
00933   char *first_artist = (char *)splt_tu_get_tags_field(state, 0, SPLT_TAGS_ARTIST);
00934   err = splt_su_copy(first_artist, &artist0);
00935   if (err < 0) { goto function_end; }
00936 
00937   char *first_album = (char *)splt_tu_get_tags_field(state, 0, SPLT_TAGS_ALBUM);
00938   err = splt_su_copy(first_album, &album0);
00939   if (err < 0) { goto function_end; }
00940 
00941   char *first_year = (char *)splt_tu_get_tags_field(state, 0, SPLT_TAGS_YEAR);
00942   err = splt_su_copy(first_year, &year0);
00943   if (err < 0) { goto function_end; }
00944 
00945   char *first_genre = (char *)splt_tu_get_tags_field(state, 0, SPLT_TAGS_GENRE);
00946   err = splt_su_copy(first_genre, &genre0);
00947   if (err < 0) { goto function_end; }
00948 
00949   int i = 0;
00950   for (i = 0; i < tracks;i++)
00951   {
00952     if (i != 0)
00953     {
00954       err = splt_tu_set_tags_field(state, i, SPLT_TAGS_ARTIST, artist0);
00955       if (err != SPLT_OK) { break; }
00956 
00957       err = splt_tu_set_tags_field(state, i, SPLT_TAGS_ALBUM, album0);
00958       if (err != SPLT_OK) { break; }
00959 
00960       err = splt_tu_set_tags_field(state, i, SPLT_TAGS_YEAR, year0);
00961       if (err != SPLT_OK) { break; }
00962 
00963       err = splt_tu_set_tags_field(state, i, SPLT_TAGS_GENRE, genre0);
00964       if (err != SPLT_OK) { break; }
00965     }
00966   }
00967 
00968 function_end:
00969   if (artist0)
00970   {
00971     free(artist0);
00972     artist0 = NULL;
00973   }
00974   if (album0)
00975   {
00976     free(album0);
00977     album0 = NULL;
00978   }
00979   if (year0)
00980   {
00981     free(year0);
00982     year0 = NULL;
00983   }
00984   if (genre0)
00985   {
00986     free(genre0);
00987     genre0 = NULL;
00988   }
00989 
00990   return err;
00991 }
00992 
00993 int splt_tu_set_field_on_tags(splt_tags *tags, int tags_field, const void *data)
00994 {
00995   int err = SPLT_OK;
00996 
00997   switch (tags_field)
00998   {
00999     case SPLT_TAGS_TITLE:
01000       err = splt_su_copy((char *)data, &tags->title);
01001       break;
01002     case SPLT_TAGS_ARTIST:
01003       err = splt_su_copy((char *)data, &tags->artist);
01004       break;
01005     case SPLT_TAGS_ALBUM:
01006       err = splt_su_copy((char *)data, &tags->album);
01007       break;
01008     case SPLT_TAGS_YEAR:
01009       err = splt_su_copy((char *)data, &tags->year);
01010       break;
01011     case SPLT_TAGS_COMMENT:
01012       err = splt_su_copy((char *)data, &tags->comment);
01013       break;
01014     case SPLT_TAGS_PERFORMER:
01015       err = splt_su_copy((char *)data, &tags->performer);
01016       break;
01017     case SPLT_TAGS_TRACK:
01018       tags->track = *((int *)data);
01019       break;
01020     case SPLT_TAGS_GENRE:
01021       err = splt_su_copy((char *)data, &tags->genre);
01022       break;
01023     case SPLT_TAGS_VERSION:
01024       tags->tags_version = *((int *)data);
01025       break;
01026     default:
01027       splt_e_error(SPLT_IERROR_INT,__func__, -500, NULL);
01028       break;
01029   }
01030 
01031   return err;
01032 }
01033 
01034