libmp3splt
|
00001 /********************************************************** 00002 * 00003 * libmp3splt -- library based on mp3splt, 00004 * for mp3/ogg splitting without decoding 00005 * 00006 * Copyright (c) 2002-2005 M. Trotta - <mtrotta@users.sourceforge.net> 00007 * Copyright (c) 2005-2011 Alexandru Munteanu - io_fx@yahoo.fr 00008 * 00009 * http://mp3splt.sourceforge.net 00010 * 00011 *********************************************************/ 00012 00013 /********************************************************** 00014 * 00015 * This program is free software; you can redistribute it and/or 00016 * modify it under the terms of the GNU General Public License 00017 * as published by the Free Software Foundation; either version 2 00018 * of the License, or (at your option) any later version. 00019 * 00020 * This program is distributed in the hope that it will be useful, 00021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 * GNU General Public License for more details. 00024 * 00025 * You should have received a copy of the GNU General Public License 00026 * along with this program; if not, write to the Free Software 00027 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 00028 * 02111-1307, 00029 * USA. 00030 * 00031 *********************************************************/ 00032 00033 #include <sys/stat.h> 00034 #include <string.h> 00035 00036 #include "splt.h" 00037 00038 #ifdef __WIN32__ 00039 #include "windows.h" 00040 #endif 00041 00042 static void close_files(splt_state *state, const char *file1, FILE **f1, 00043 const char *file2, FILE **f2, int *error); 00044 00045 void splt_check_points_inf_song_length(splt_state *state, int *error) 00046 { 00047 if (splt_io_input_is_stdin(state)) 00048 { 00049 return; 00050 } 00051 00052 int splitnumber = splt_t_get_splitnumber(state); 00053 if (splitnumber < 1) 00054 { 00055 return; 00056 } 00057 00058 int err = SPLT_OK; 00059 int found_max_splitpoint = SPLT_FALSE; 00060 long total_time = splt_t_get_total_time(state); 00061 00062 int i = 0; 00063 for (i = 0; i < splitnumber - 1; i++) 00064 { 00065 long splitpoint_value = splt_sp_get_splitpoint_value(state, i, &err); 00066 if (err < SPLT_OK) { *error = err; return; } 00067 00068 if (splitpoint_value > total_time) 00069 { 00070 found_max_splitpoint = SPLT_TRUE; 00071 splt_t_set_splitnumber(state, i+1); 00072 00073 *error = SPLT_SPLITPOINT_BIGGER_THAN_LENGTH; 00074 splt_e_set_error_data_from_splitpoint(state, splitpoint_value); 00075 splt_sp_set_splitpoint_value(state, i, total_time); 00076 00077 break; 00078 } 00079 } 00080 } 00081 00082 void splt_check_if_points_in_order(splt_state *state, int *error) 00083 { 00084 int splitnumber = splt_t_get_splitnumber(state); 00085 if (splitnumber < 1) 00086 { 00087 return; 00088 } 00089 00090 int err = SPLT_OK; 00091 int i = 0; 00092 for (i = 0; i < (splitnumber-1); i++) 00093 { 00094 long splitpoint_value = splt_sp_get_splitpoint_value(state, i, &err); 00095 if (err != SPLT_OK) { *error = err; return; } 00096 long next_splitpoint_value = splt_sp_get_splitpoint_value(state, i+1, &err); 00097 if (err != SPLT_OK) { *error = err; return; } 00098 00099 if (splitpoint_value < 0) 00100 { 00101 splt_e_set_error_data_from_splitpoint(state, splitpoint_value); 00102 *error = SPLT_ERROR_NEGATIVE_SPLITPOINT; 00103 return; 00104 } 00105 00106 if (splitpoint_value == LONG_MAX) 00107 { 00108 splt_sp_set_splitpoint_value(state, i, splt_t_get_total_time(state)); 00109 } 00110 00111 if (splitpoint_value > next_splitpoint_value) 00112 { 00113 splt_e_set_error_data_from_splitpoints(state, 00114 splitpoint_value, next_splitpoint_value); 00115 *error = SPLT_ERROR_SPLITPOINTS_NOT_IN_ORDER; 00116 return; 00117 } 00118 00119 if (splitpoint_value == next_splitpoint_value) 00120 { 00121 splt_e_set_error_data_from_splitpoint(state, splitpoint_value); 00122 *error = SPLT_ERROR_EQUAL_SPLITPOINTS; 00123 return; 00124 } 00125 } 00126 } 00127 00128 void splt_check_if_fname_path_is_correct(splt_state *state, 00129 const char *fname_path, int *error) 00130 { 00131 splt_d_print_debug(state,"Check if the new filename path is correct _%s_\n",fname_path); 00132 00133 char current_directory[4] = { '\0' }; 00134 snprintf(current_directory, 4, "%c%c", '.', SPLT_DIRCHAR); 00135 00136 if ((strcmp(fname_path, "") != 0) && 00137 (strcmp(fname_path, current_directory) != 0)) 00138 { 00139 if (!splt_io_check_if_directory(fname_path)) 00140 { 00141 splt_e_set_strerr_msg_with_data(state, 00142 _("directory does not exists"), fname_path); 00143 *error = SPLT_ERROR_INCORRECT_PATH; 00144 } 00145 } 00146 } 00147 00148 char *splt_check_put_dir_of_cur_song(const char *filename, 00149 const char *path, int *error) 00150 { 00151 int err = SPLT_OK; 00152 char *filename_path = NULL; 00153 00154 if (path == NULL || path[0] == '\0') 00155 { 00156 err = splt_su_copy(filename, &filename_path); 00157 if (err < 0) { *error = err; return NULL; } 00158 00159 char *c = strrchr(filename_path, SPLT_DIRCHAR); 00160 if (c == NULL) 00161 { 00162 filename_path[0] = '\0'; 00163 return filename_path; 00164 } 00165 00166 *(c+1) = '\0'; 00167 return filename_path; 00168 } 00169 00170 err = splt_su_copy(path, &filename_path); 00171 if (err < 0) { *error = err; return NULL; } 00172 00173 return filename_path; 00174 } 00175 00176 int splt_check_compatible_options(splt_state *state) 00177 { 00178 return SPLT_TRUE; 00179 } 00180 00181 void splt_check_set_correct_options(splt_state *state) 00182 { 00183 splt_d_print_debug(state,"Check and set correct options...\n"); 00184 00185 int split_mode = splt_o_get_int_option(state,SPLT_OPT_SPLIT_MODE); 00186 00187 if (( split_mode == SPLT_OPTION_SILENCE_MODE) 00188 || splt_o_get_int_option(state,SPLT_OPT_AUTO_ADJUST)) 00189 { 00190 splt_o_set_int_option(state, SPLT_OPT_FRAME_MODE, SPLT_OPT_FRAME_MODE); 00191 00192 if ((splt_o_get_float_option(state,SPLT_OPT_PARAM_THRESHOLD) < -96.f) || 00193 (splt_o_get_float_option(state,SPLT_OPT_PARAM_THRESHOLD) > 0.f)) 00194 { 00195 splt_o_set_float_option(state,SPLT_OPT_PARAM_THRESHOLD, SPLT_DEFAULT_PARAM_THRESHOLD); 00196 } 00197 00198 if ((splt_o_get_float_option(state,SPLT_OPT_PARAM_OFFSET) < -2.f) || 00199 (splt_o_get_float_option(state,SPLT_OPT_PARAM_OFFSET) > 2.f)) 00200 { 00201 splt_o_set_float_option(state,SPLT_OPT_PARAM_OFFSET, SPLT_DEFAULT_PARAM_OFFSET); 00202 } 00203 00204 if (splt_o_get_int_option(state,SPLT_OPT_PARAM_GAP) < 0) 00205 { 00206 splt_o_set_int_option(state,SPLT_OPT_PARAM_GAP, SPLT_DEFAULT_PARAM_GAP); 00207 } 00208 00209 if (splt_o_get_float_option(state,SPLT_OPT_PARAM_MIN_LENGTH) < 0.f) 00210 { 00211 splt_o_set_float_option(state, SPLT_OPT_PARAM_MIN_LENGTH, SPLT_DEFAULT_PARAM_MINIMUM_LENGTH); 00212 splt_o_set_int_option(state, SPLT_OPT_AUTO_ADJUST, SPLT_FALSE); 00213 } 00214 } 00215 00216 if (!splt_o_get_int_option(state,SPLT_OPT_AUTO_ADJUST)) 00217 { 00218 splt_o_set_int_option(state,SPLT_OPT_PARAM_GAP, 0); 00219 } 00220 00221 if ((splt_o_get_int_option(state,SPLT_OPT_INPUT_NOT_SEEKABLE)) && 00222 (splt_o_get_int_option(state,SPLT_OPT_AUTO_ADJUST) || 00223 (split_mode == SPLT_OPTION_SILENCE_MODE) || 00224 (split_mode == SPLT_OPTION_ERROR_MODE) || 00225 (split_mode == SPLT_OPTION_WRAP_MODE))) 00226 { 00227 splt_o_set_int_option(state, SPLT_OPT_INPUT_NOT_SEEKABLE, SPLT_FALSE); 00228 } 00229 } 00230 00231 void splt_check_file_type(splt_state *state, int *error) 00232 { 00233 int err = SPLT_OK; 00234 00235 splt_d_print_debug(state,"Detecting file format...\n"); 00236 const char *filename = splt_t_get_filename_to_split(state); 00237 00238 splt_d_print_debug(state,"Checking the format of _%s_\n", filename); 00239 00240 splt_plugins *pl = state->plug; 00241 int plugin_found = SPLT_FALSE; 00242 int i = 0; 00243 for (i = 0;i < pl->number_of_plugins_found;i++) 00244 { 00245 splt_p_set_current_plugin(state, i); 00246 err = SPLT_OK; 00247 00248 if (splt_o_get_int_option(state, SPLT_OPT_INPUT_NOT_SEEKABLE) && 00249 ! splt_io_input_is_stdin(state)) 00250 { 00251 const char *extension = splt_p_get_extension(state, &err); 00252 const char *upper_extension = splt_p_get_extension(state, &err); 00253 if (err == SPLT_OK) 00254 { 00255 if (splt_su_str_ends_with(filename, extension) || 00256 splt_su_str_ends_with(filename, upper_extension)) 00257 { 00258 plugin_found = SPLT_TRUE; 00259 break; 00260 } 00261 } 00262 } 00263 else 00264 { 00265 if (splt_p_check_plugin_is_for_file(state, &err)) 00266 { 00267 if (err == SPLT_OK) 00268 { 00269 plugin_found = SPLT_TRUE; 00270 break; 00271 } 00272 } 00273 } 00274 } 00275 00276 if (! plugin_found) 00277 { 00278 splt_e_set_error_data(state, filename); 00279 *error = SPLT_ERROR_NO_PLUGIN_FOUND_FOR_FILE; 00280 splt_d_print_debug(state,"No plugin found !\n"); 00281 splt_d_print_debug(state,"Verifying if the file _%s_ is a file ...\n", filename); 00282 00283 FILE *test = NULL; 00284 if ((test = splt_io_fopen(filename,"r")) == NULL) 00285 { 00286 splt_e_set_strerror_msg_with_data(state, filename); 00287 *error = SPLT_ERROR_CANNOT_OPEN_FILE; 00288 return; 00289 } 00290 00291 if (fclose(test) != 0) 00292 { 00293 splt_e_set_strerror_msg_with_data(state, filename); 00294 *error = SPLT_ERROR_CANNOT_CLOSE_FILE; 00295 return; 00296 } 00297 } 00298 } 00299 00300 int splt_check_is_the_same_file(splt_state *state, const char *file1, 00301 const char *file2, int *error) 00302 { 00303 if (file1 == NULL || file2 == NULL) 00304 { 00305 return SPLT_FALSE; 00306 } 00307 00308 FILE *file1_ = NULL; 00309 FILE *file2_ = NULL; 00310 00311 if (file1[strlen(file1) - 1] == '-') 00312 { 00313 return SPLT_FALSE; 00314 } 00315 00316 splt_d_print_debug(state,"Checking if _%s_ is like _%s_ \n", file1, file2); 00317 00318 int is_file1 = splt_io_check_if_file(state, file1); 00319 int is_file2 = splt_io_check_if_file(state, file2); 00320 if (!is_file1 || !is_file2) 00321 { 00322 return SPLT_FALSE; 00323 } 00324 00325 if ((file1_ = splt_io_fopen(file1,"r")) == NULL) 00326 { 00327 goto end; 00328 } 00329 00330 if ((file2_ = splt_io_fopen(file2,"r")) == NULL) 00331 { 00332 goto end; 00333 } 00334 00335 //mingw for windows returns 0 as inode and 0 as device 00336 //when using the fstat function. 00337 #ifdef __WIN32__ 00338 BY_HANDLE_FILE_INFORMATION handle_info_file1; 00339 BY_HANDLE_FILE_INFORMATION handle_info_file2; 00340 int file1_d = fileno(file1_); 00341 int file2_d = fileno(file2_); 00342 00343 if (!GetFileInformationByHandle((HANDLE)_get_osfhandle(file1_d), &handle_info_file1)) 00344 { 00345 goto end; 00346 } 00347 if (!GetFileInformationByHandle((HANDLE)_get_osfhandle(file2_d), &handle_info_file2)) 00348 { 00349 goto end; 00350 } 00351 00352 if ((handle_info_file1.nFileIndexHigh == handle_info_file2.nFileIndexHigh)&& 00353 (handle_info_file1.nFileIndexLow == handle_info_file2.nFileIndexLow)) 00354 { 00355 close_files(state, file1, &file1_,file2, &file2_,error); 00356 return SPLT_TRUE; 00357 } 00358 #else 00359 int file1_d = fileno(file1_); 00360 struct stat file1_stat; 00361 if (fstat(file1_d, &file1_stat) != 0) 00362 { 00363 goto end; 00364 } 00365 00366 int file2_d = fileno(file2_); 00367 struct stat file2_stat; 00368 if (fstat(file2_d,&file2_stat) != 0) 00369 { 00370 goto end; 00371 } 00372 00373 if ((file1_stat.st_ino == file2_stat.st_ino) && 00374 (file1_stat.st_dev == file2_stat.st_dev)) 00375 { 00376 close_files(state, file1, &file1_,file2, &file2_,error); 00377 return SPLT_TRUE; 00378 } 00379 #endif 00380 00381 end: 00382 close_files(state, file1, &file1_,file2, &file2_,error); 00383 00384 return SPLT_FALSE; 00385 } 00386 00387 static void close_files(splt_state *state, const char *file1, FILE **f1, 00388 const char *file2, FILE **f2, int *error) 00389 { 00390 if (*f1) 00391 { 00392 if (fclose(*f1) != 0) 00393 { 00394 splt_e_set_strerror_msg_with_data(state, file1); 00395 *error = SPLT_ERROR_CANNOT_CLOSE_FILE; 00396 } 00397 else 00398 { 00399 *f1 = NULL; 00400 } 00401 } 00402 00403 if (*f2) 00404 { 00405 if (fclose(*f2) != 0) 00406 { 00407 splt_e_set_strerror_msg_with_data(state, file2); 00408 *error = SPLT_ERROR_CANNOT_CLOSE_FILE; 00409 } 00410 else 00411 { 00412 *f2 = NULL; 00413 } 00414 } 00415 } 00416