00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00031 #include <string.h>
00032 #include <ctype.h>
00033
00034 #include "splt.h"
00035 #include "cddb_cue_common.h"
00036
00037 #include "cue.h"
00038
00040 static void splt_cue_process_track_line(char *line_content, cue_utils *cu, splt_state *state)
00041 {
00042
00043 line_content += 5;
00044
00045 if (cu->tracks == -1)
00046 {
00047 cu->tracks = 0;
00048 }
00049
00050 if (!cu->time_for_track)
00051 {
00052 splt_e_set_error_data(state, cu->file);
00053 cu->error = SPLT_INVALID_CUE_FILE;
00054 }
00055
00056 cu->performer = SPLT_FALSE;
00057 cu->title = SPLT_FALSE;
00058 cu->time_for_track = SPLT_FALSE;
00059 cu->tracks++;
00060 cu->current_track_type = SPLT_SPLITPOINT;
00061
00062 splt_tu_new_tags_if_necessary(state, cu->tracks - 1);
00063 }
00064
00065 static void remove_trailing_spaces_and_quote(char *ptr_e, char *in)
00066 {
00067 if (ptr_e)
00068 {
00069 ptr_e--;
00070
00071 while (*ptr_e == ' ' && ptr_e > in)
00072 {
00073 ptr_e--;
00074 }
00075
00076 if (ptr_e > in)
00077 {
00078 if (*ptr_e == '"')
00079 {
00080 *ptr_e = '\0';
00081 }
00082 else
00083 {
00084 *(ptr_e + 1) = '\0';
00085 }
00086 }
00087 }
00088 }
00089
00090 static const char *splt_cue_parse_value(char *in, int skip_last_word)
00091 {
00092 char *ptr_b = in;
00093 char *ptr_e = NULL;
00094
00095 while (*ptr_b == ' ')
00096 {
00097 ptr_b++;
00098 }
00099
00100 if (*ptr_b == '"')
00101 {
00102 ptr_b++;
00103 }
00104
00105 ptr_e = strchr(ptr_b + 1, '\0');
00106
00107 remove_trailing_spaces_and_quote(ptr_e, in);
00108
00109 if (skip_last_word)
00110 {
00111 ptr_e = strrchr(ptr_b, ' ');
00112 remove_trailing_spaces_and_quote(ptr_e, in);
00113 }
00114
00115 return ptr_b;
00116 }
00117
00119 static int splt_cue_store_value(splt_state *state, char *in,
00120 int index, int tag_field)
00121 {
00122 if (!in)
00123 {
00124 return SPLT_OK;
00125 }
00126
00127 const char *ptr_b = splt_cue_parse_value(in, SPLT_FALSE);
00128
00129 char *out = NULL;
00130 int error = splt_su_append(&out, ptr_b, strlen(ptr_b) + 1, NULL);
00131 if (error < 0) { return error; }
00132
00133 if (tag_field == SPLT_TAGS_ARTIST)
00134 {
00135 splt_c_put_info_message_to_client(state, _("\n Artist: %s\n"), out);
00136 }
00137 else if (tag_field == SPLT_TAGS_ALBUM)
00138 {
00139 splt_c_put_info_message_to_client(state, _(" Album: %s\n"), out);
00140 }
00141
00142 error = splt_tu_set_tags_field(state, index, tag_field, out);
00143 if (out)
00144 {
00145 free(out);
00146 out = NULL;
00147 }
00148
00149 return error;
00150 }
00151
00153 static void splt_cue_process_title_line(char *line_content, cue_utils *cu, splt_state *state)
00154 {
00155 int err = SPLT_OK;
00156
00157
00158 line_content += 5;
00159
00160 if (cu->tracks == -1)
00161 {
00162 if ((err = splt_cue_store_value(state, line_content,
00163 0, SPLT_TAGS_ALBUM)) != SPLT_OK)
00164 {
00165 cu->error = err;
00166 return;
00167 }
00168 }
00169 else
00170 {
00171 if (cu->tracks > 0)
00172 {
00173 if ((err = splt_cue_store_value(state, line_content,
00174 cu->tracks-1, SPLT_TAGS_TITLE)) != SPLT_OK)
00175 {
00176 cu->error = err;
00177 return;
00178 }
00179 }
00180
00181 cu->title = SPLT_TRUE;
00182 }
00183 }
00184
00186 static void splt_cue_process_performer_line(char *line_content, cue_utils *cu, splt_state *state)
00187 {
00188 int err = SPLT_OK;
00189
00190
00191 line_content += 9;
00192
00193 if (cu->tracks == -1)
00194 {
00195
00196
00197 if ((err = splt_cue_store_value(state, line_content,
00198 0, SPLT_TAGS_ARTIST)) != SPLT_OK)
00199 {
00200 cu->error = err;
00201 return;
00202 }
00203 }
00204 else
00205 {
00206 if (cu->tracks > 0)
00207 {
00208 if ((err = splt_cue_store_value(state, line_content,
00209 cu->tracks - 1, SPLT_TAGS_PERFORMER)) != SPLT_OK)
00210 {
00211 cu->error = err;
00212 return;
00213 }
00214 }
00215
00216 cu->performer = SPLT_TRUE;
00217 }
00218
00219 }
00220
00221
00223 static void splt_cue_process_index_line(char *line_content, cue_utils *cu, splt_state *state)
00224 {
00225 int err = SPLT_OK;
00226
00227 line_content += 9;
00228
00229 if (cu->tracks <= 0)
00230 {
00231 return;
00232 }
00233
00234 char *trimmed_line = splt_su_trim_spaces(line_content);
00235
00236 long hundr_seconds = splt_co_convert_to_hundreths(trimmed_line);
00237 if (hundr_seconds == -1)
00238 {
00239 splt_e_set_error_data(state, cu->file);
00240 cu->error = SPLT_INVALID_CUE_FILE;
00241 return;
00242 }
00243
00244 err = splt_sp_append_splitpoint(state, hundr_seconds, NULL,
00245 cu->current_track_type);
00246 if (err < 0) { cu->error = err; return; }
00247
00248 cu->time_for_track = SPLT_TRUE;
00249 cu->counter++;
00250 }
00251
00253 static void splt_cue_process_rem_line(char *line_content, cue_utils *cu, splt_state *state)
00254 {
00255 char *linetail;
00256
00257
00258 line_content += 3;
00259
00260
00261 while ((*line_content==' ')||(*line_content=='\t')) line_content++;
00262
00263 if((linetail=strstr(line_content,"CREATOR"))!=NULL)
00264 {
00265
00266 linetail += 7;
00267
00268 if(strstr(linetail,"MP3SPLT_GTK")!=NULL)
00269 {
00270 cu->file_has_been_created_by_us = SPLT_TRUE;
00271 }
00272 }
00273 else if((linetail=strstr(line_content,"SPLT_TITLE_IS_FILENAME"))!=NULL)
00274 {
00275 cu->title_is_filename = SPLT_TRUE;
00276 }
00277 else if((linetail=strstr(line_content,"NOKEEP"))!=NULL)
00278 {
00279 if (cu->tracks >= 0)
00280 cu->current_track_type=SPLT_SKIPPOINT;
00281 }
00282 }
00283
00285 static void splt_cue_process_file_line(char *line_content, cue_utils *cu, splt_state *state)
00286 {
00287 if (!splt_o_get_int_option(state, SPLT_OPT_SET_FILE_FROM_CUE_IF_FILE_TAG_FOUND))
00288 {
00289 return;
00290 }
00291
00292
00293 line_content += 4;
00294
00295 int err = SPLT_OK;
00296
00297 const char *file_from_cue = splt_cue_parse_value(line_content, SPLT_TRUE);
00298
00299 if (splt_io_check_if_file(NULL, file_from_cue))
00300 {
00301 err = splt_t_set_filename_to_split(state, file_from_cue);
00302 if (err < 0) { cu->error = err; }
00303 return;
00304 }
00305
00306 char *file_from_cue_with_path = NULL;
00307 splt_su_copy(cu->file, &file_from_cue_with_path);
00308 splt_su_keep_path_and_remove_filename(file_from_cue_with_path);
00309 splt_su_append_str(&file_from_cue_with_path, SPLT_DIRSTR, file_from_cue, NULL);
00310
00311 if (splt_io_check_if_file(NULL, file_from_cue_with_path))
00312 {
00313 err = splt_t_set_filename_to_split(state, file_from_cue_with_path);
00314 }
00315
00316 if (file_from_cue_with_path)
00317 {
00318 free(file_from_cue_with_path);
00319 file_from_cue_with_path = NULL;
00320 }
00321
00322 if (err < 0) { cu->error = err; return; }
00323 }
00324
00328 static void splt_cue_process_line(char **l, cue_utils *cu, splt_state *state)
00329 {
00330 if (!l || !*l) { return; }
00331
00332 char *line = *l;
00333
00334 splt_su_line_to_unix(line);
00335 splt_su_str_cut_last_char(line);
00336
00337 splt_t_clean_one_split_data(state, cu->tracks);
00338
00339 char *line_content = NULL;
00340 if (((line_content = strstr(line, "TRACK")) != NULL)
00341 && (strstr(line, "AUDIO") != NULL))
00342 {
00343 splt_cue_process_track_line(line_content, cu, state);
00344 }
00345 else if ((line_content = strstr(line, "REM")) != NULL)
00346 {
00347 splt_cue_process_rem_line(line_content, cu, state);
00348 }
00349 else if ((line_content = strstr(line, "TITLE")) != NULL)
00350 {
00351 splt_cue_process_title_line(line_content, cu, state);
00352 }
00353 else if ((line_content = strstr(line, "PERFORMER")) != NULL)
00354 {
00355 splt_cue_process_performer_line(line_content, cu, state);
00356 }
00357 else if ((line_content = strstr(line, "INDEX 01")) != NULL)
00358 {
00359 splt_cue_process_index_line(line_content, cu, state);
00360 }
00361 else if ((line_content = strstr(line, "FILE")) != NULL)
00362 {
00363 splt_cue_process_file_line(line_content, cu, state);
00364 }
00365
00366 free(*l);
00367 *l = NULL;
00368 }
00369
00370
00371
00372
00373
00374
00375
00376
00377 static cue_utils *splt_cue_cu_new(int *error)
00378 {
00379 cue_utils *cu = malloc(sizeof(cue_utils));
00380 if (cu == NULL)
00381 {
00382 *error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
00383 return NULL;
00384 }
00385
00386 cu->tracks = -1;
00387 cu->time_for_track = SPLT_TRUE;
00388 cu->performer = SPLT_FALSE;
00389 cu->title = SPLT_FALSE;
00390 cu->counter = 0;
00391 cu->file = NULL;
00392 cu->error = SPLT_OK;
00393 cu->current_track_type = SPLT_SPLITPOINT;
00394 cu->title_is_filename = SPLT_FALSE;
00395 cu->file_has_been_created_by_us = SPLT_FALSE;
00396
00397 return cu;
00398 }
00399
00405 static void splt_cue_cu_free(cue_utils **cu)
00406 {
00407 if (!cu || !*cu)
00408 {
00409 return;
00410 }
00411
00412 free(*cu);
00413 *cu = NULL;
00414 }
00415
00425 int splt_cue_put_splitpoints(const char *file, splt_state *state, int *error)
00426 {
00427 if (file == NULL)
00428 {
00429 splt_e_set_error_data(state, file);
00430 *error = SPLT_INVALID_CUE_FILE;
00431 return 0;
00432 }
00433
00434 splt_c_put_info_message_to_client(state,
00435 _(" reading informations from CUE file %s ...\n"),file);
00436
00437 splt_t_free_splitpoints_tags(state);
00438
00439 *error = SPLT_CUE_OK;
00440
00441 int err = SPLT_OK;
00442 FILE *file_input = NULL;
00443 char *line = NULL;
00444 int tracks = -1;
00445
00446 cue_utils *cu = splt_cue_cu_new(&err);
00447
00448 if (err < 0) { *error = err; return tracks; }
00449 cu->file = file;
00450
00451
00452 err = splt_tu_set_tags_field(state, 0, SPLT_TAGS_GENRE, SPLT_UNDEFINED_GENRE);
00453 if (err != SPLT_OK)
00454 {
00455 *error = err;
00456 return tracks;
00457 }
00458
00459 if (!(file_input=splt_io_fopen(file, "r")))
00460 {
00461 splt_e_set_strerror_msg_with_data(state, file);
00462 *error = SPLT_ERROR_CANNOT_OPEN_FILE;
00463 return tracks;
00464 }
00465
00466 if (fseek(file_input, 0, SEEK_SET) != 0)
00467 {
00468 splt_e_set_strerror_msg_with_data(state, file);
00469 *error = SPLT_ERROR_SEEKING_FILE;
00470 goto function_end;
00471 }
00472
00473 while ((line = splt_io_readline(file_input, error)) != NULL)
00474 {
00475 if (*error < 0) { goto function_end; }
00476
00477 splt_cue_process_line(&line, cu, state);
00478 tracks = cu->tracks;
00479 if (cu->error < 0) { *error = cu->error; goto function_end; }
00480 }
00481
00482
00483
00484
00485 if(!cu->file_has_been_created_by_us)
00486 err = splt_sp_append_splitpoint(state, LONG_MAX,
00487 _("description here"), cu->current_track_type);
00488
00489 if (cu->counter == 0)
00490 {
00491 splt_e_set_error_data(state, file);
00492 *error = SPLT_INVALID_CUE_FILE;
00493 goto function_end;
00494 }
00495
00496 if (!cu->time_for_track)
00497 {
00498 tracks--;
00499 }
00500
00501
00502 splt_cc_put_filenames_from_tags(state, tracks, error);
00503
00504
00505
00506
00507
00508
00509
00510
00511 if(cu->title_is_filename)
00512 {
00513 int i;
00514 for(i=0;i<tracks;i++)
00515 {
00516 splt_sp_set_splitpoint_name(state, i,
00517 splt_tu_get_tags_field(state, i, SPLT_TAGS_TITLE));
00518 }
00519 }
00520
00521 function_end:
00522 splt_cue_cu_free(&cu);
00523
00524 if (line)
00525 {
00526 free(line);
00527 line = NULL;
00528 }
00529
00530 if (fclose(file_input) != 0)
00531 {
00532 splt_e_set_strerror_msg_with_data(state, file);
00533 *error = SPLT_ERROR_CANNOT_CLOSE_FILE;
00534 }
00535 file_input = NULL;
00536
00537 if (*error >= 0)
00538 {
00539 splt_c_put_info_message_to_client(state, _(" Tracks: %d\n\n"), tracks);
00540 }
00541
00542 return tracks;
00543 }
00544
00554 static void splt_cue_write_title_performer(splt_state *state, FILE *file_output,
00555 int tags_index, short with_spaces, short write_album)
00556 {
00557 splt_tags *tags = NULL;
00558 if (tags_index >= 0)
00559 {
00560 tags = splt_tu_get_tags_at(state, tags_index);
00561 }
00562 else
00563 {
00564 tags = splt_tu_get_current_tags(state);
00565 }
00566
00567 if (tags)
00568 {
00569 if (write_album)
00570 {
00571 if (tags->album)
00572 {
00573 if (with_spaces) { fprintf(file_output, " "); }
00574 fprintf(file_output, "TITLE \"%s\"\n", tags->album);
00575 }
00576 }
00577 else
00578 {
00579 if (tags->title)
00580 {
00581 if (with_spaces) { fprintf(file_output, " "); }
00582 fprintf(file_output, "TITLE \"%s\"\n", tags->title);
00583 }
00584 }
00585
00586 char *performer = splt_tu_get_artist_or_performer_ptr(tags);
00587 if (performer)
00588 {
00589 if (with_spaces) { fprintf(file_output, " "); }
00590 fprintf(file_output, "PERFORMER \"%s\"\n", performer);
00591 }
00592 }
00593 else
00594 {
00595 if (with_spaces) { fprintf(file_output, " "); }
00596 fprintf(file_output, "TITLE \"\"\n");
00597 if (with_spaces) { fprintf(file_output, " "); }
00598 fprintf(file_output, "PERFORMER \"\"\n");
00599 }
00600 }
00601
00612 void splt_cue_export_to_file(splt_state *state, const char *out_file,
00613 short stop_at_total_time, int *error)
00614 {
00615 int err = SPLT_OK;
00616
00617 int num_of_splitpoints = splt_t_get_splitnumber(state);
00618 if (num_of_splitpoints <= 0)
00619 {
00620 return;
00621 }
00622
00623 long total_time = splt_t_get_total_time(state);
00624 FILE *file_output = NULL;
00625
00626 splt_d_print_debug(state, "Cue output file without output path = _%s_\n", out_file);
00627
00628 char *dup_out_file = NULL;
00629 err = splt_su_copy(out_file, &dup_out_file);
00630 if (err < 0) { *error = err; return; }
00631 char *cue_out_file = splt_su_get_file_with_output_path(state, dup_out_file, &err);
00632 free(dup_out_file);
00633 dup_out_file = NULL;
00634 if (err < 0) { *error = err; goto end; }
00635
00636 splt_d_print_debug(state, "Cue output file with output path = _%s_\n", cue_out_file);
00637
00638 if (!(file_output = splt_io_fopen(cue_out_file, "w")))
00639 {
00640 splt_e_set_strerror_msg_with_data(state, cue_out_file);
00641 *error = SPLT_ERROR_CANT_WRITE_TO_OUTPUT_FILE;
00642 goto end;
00643 }
00644
00645 splt_cue_write_title_performer(state, file_output, 0, SPLT_FALSE, SPLT_TRUE);
00646
00647 char *fname = splt_t_get_filename_to_split(state);
00648
00649 char new_upper_ext[10] = { '\0' };
00650 const char *upper_ext = splt_p_get_upper_extension(state, &err);
00651 int i = 0;
00652 for (i = 1;i < strlen(upper_ext);i++)
00653 {
00654 new_upper_ext[i-1] = upper_ext[i];
00655 }
00656
00657 fprintf(file_output, "FILE \"%s\" %s\n", fname, new_upper_ext);
00658 if (err < 0) { *error = err; goto end; }
00659
00660 splt_t_set_current_split(state, 0);
00661 for (i = 0;i < num_of_splitpoints;i++)
00662 {
00663 long splitpoint = splt_sp_get_splitpoint_value(state, i, &err);
00664 if (err < 0) { *error = err; break; }
00665
00666
00667
00668 if (stop_at_total_time &&
00669 (total_time > 0 && splitpoint >= total_time))
00670 {
00671 break;
00672 }
00673
00674 fprintf(file_output, " TRACK %02d AUDIO\n", i+1);
00675
00676 splt_cue_write_title_performer(state, file_output, -1, SPLT_TRUE, SPLT_FALSE);
00677
00678 long mins = 0, secs = 0, hundr = 0;
00679 if (splitpoint == LONG_MAX)
00680 {
00681 splitpoint = total_time;
00682 }
00683
00684 splt_sp_get_mins_secs_hundr_from_splitpoint(splitpoint, &mins, &secs, &hundr);
00685 fprintf(file_output, " INDEX 01 %02ld:%02ld:%02ld\n", mins, secs, hundr);
00686
00687 splt_t_current_split_next(state);
00688 }
00689
00690 end:
00691 fflush(file_output);
00692 if (fclose(file_output) != 0)
00693 {
00694 splt_e_set_strerror_msg_with_data(state, cue_out_file);
00695 *error = SPLT_ERROR_CANNOT_CLOSE_FILE;
00696 }
00697 file_output = NULL;
00698
00699 splt_c_put_info_message_to_client(state,
00700 _(" CUE file '%s' created.\n"), cue_out_file);
00701
00702 if (cue_out_file)
00703 {
00704 free(cue_out_file);
00705 cue_out_file = NULL;
00706 }
00707 }
00708