From 1c99cefdf2a83afe062235d421fa2ea216fcdb94 Mon Sep 17 00:00:00 2001 From: Matteo Paonessa Date: Sat, 30 May 2015 12:33:57 +0200 Subject: [PATCH] Made compression routine a function --- src/main.c | 185 ++++++++++++++++++++++++++++++---------------------- src/utils.c | 88 +++++++++++++++++++++++-- src/utils.h | 1 + 3 files changed, 188 insertions(+), 86 deletions(-) diff --git a/src/main.c b/src/main.c index 463edd9..43fc8dc 100755 --- a/src/main.c +++ b/src/main.c @@ -7,7 +7,6 @@ #include #include #include -#include #include "lossless.h" #include "compress.h" @@ -24,10 +23,114 @@ -R recursive */ + + //TODO Use a general fuction to support folder separators -int main (int argc, char *argv[]) { +void cclt_start(char** input_files, int n, char* output_folder, cclt_compress_parameters* pars, off_t* i_t_size, off_t* o_t_size) { struct stat st_buf; + int i = 0, lossless = pars->lossless, exif = pars->exif_copy, recursive = pars->recursive; + + if (mkpath(output_folder, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == -1) { + if (errno != EEXIST) { + exit(-5); + } + } + + while (i < n) { + off_t i_size, o_size; + int status; //Pointer for stat() call + char* output_filename = (char*) malloc ((strlen(output_folder) + 2) * sizeof(char)); + char* i_tmp = (char*) malloc (strlen(input_files[i]) * sizeof(char)); + + strcpy(i_tmp, input_files[i]); + strcpy(output_filename, output_folder); + + //Append / if was not entered by user + if (output_filename[strlen(output_folder) - 1] != '/') { + strcat(output_filename, "/"); + } + + output_filename = realloc(output_filename, (strlen(output_filename) + strlen(get_filename_with_extension(i_tmp)) + 1) * sizeof(char)); + output_filename = strcat(output_filename, get_filename_with_extension(i_tmp)); + + //TODO OVERALL progress update? + //print_progress(i + 1, pars.input_files_count, "Progress: "); + + //Get input stats + status = stat(input_files[i], &st_buf); + if (status != 0) { + fprintf(stderr, "Failed to get input file stats. Aborting.\n"); + exit(-11); + } + + //Check if we ran into a folder + //TODO Check symlinks too + if (S_ISDIR (st_buf.st_mode) && recursive == 0) { + //Folder found, but we don't need it here + i++; + continue; + } else if (S_ISDIR (st_buf.st_mode) && recursive != 0) { + //Folder found, we need to get into it + + + /* + 1. Scan the entire folder input_files[i] + 2. Get a new array containing all the files and folders + 3. Set the output folder to be one step deeper + 3. Call cclt_start(new_list, new folder, same, same, same) + */ + + //TODO malloc? + //char** new_files = (char**) malloc(256 * sizeof(char*)); + //new_files = scan_folder(input_files[i], 0); + //cclt_start(new_files, output_folder, pars, i_t_size, o_t_size); + //i++; + //TODO Remove this after this funcion is fully completed + //free(new_files); + continue; + } + + //Get input file size + i_size = st_buf.st_size; + *(i_t_size) += i_size; + + //TODO Do we want a more verbose output? + fprintf(stdout, "Compressing: %s -> %s\n", input_files[i], output_filename); + + if (lossless != 0) { + cclt_optimize(input_files[i], output_filename, exif, input_files[i]); + } else { + cclt_compress_routine(input_files[i], output_filename, pars); + } + + //Get output stats + status = stat(output_filename, &st_buf); + if (status != 0) { + //TODO This is not critical, but still something to be tracked + fprintf(stderr, "Failed to get output file stats. Aborting.\n"); + exit(-12); + } + o_size = st_buf.st_size; + *(o_t_size) += o_size; + + fprintf(stdout, "%ld bytes -> %ld bytes [%.2f%%]\n", + (long) i_size, (long) o_size, ((float) o_size - i_size) * 100 / i_size); + + //TODO Perform the required instructions + //TODO Provide complete progress support + //INPUT: pars.input_files[i] | OUTPUT: output_filename + + //Free allocated memory + //TODO Causing segfaults + //free(output_filename); + //free(i_tmp); + i++; + } + +} + +int main (int argc, char *argv[]) { errno = 0; off_t i_t_size = 0, o_t_size = 0; @@ -82,83 +185,7 @@ int main (int argc, char *argv[]) { exit(-13); } - - //This is the main loop. It iterates through all the input files provided. - //It also extract the original filename to be saved in the new destination. - //TODO Provide support for folder structure. - for (int i = 0; i < pars.input_files_count; i++) { - off_t i_size, o_size; - int status; //Pointer for stat() call - char* output_filename = (char*) malloc ((strlen(pars.output_folder) + 2) * sizeof(char)); - char* i_tmp = (char*) malloc (strlen(pars.input_files[i]) * sizeof(char)); - - strcpy(i_tmp, pars.input_files[i]); - strcpy(output_filename, pars.output_folder); - - //Append / if was not entered by user - if (output_filename[strlen(pars.output_folder - 1)] != '/') { - strcat(output_filename, "/"); - } - - output_filename = realloc(output_filename, (strlen(output_filename) + strlen(get_filename_with_extension(i_tmp)) + 1) * sizeof(char)); - - output_filename = strcat(output_filename, get_filename_with_extension(i_tmp)); - - //TODO OVERALL progress update? - //print_progress(i + 1, pars.input_files_count, "Progress: "); - - //Get input stats - status = stat(pars.input_files[i], &st_buf); - if (status != 0) { - fprintf(stderr, "Failed to get input file stats. Aborting.\n"); - exit(-11); - } - - //If the input is a folder, skip - if (S_ISDIR (st_buf.st_mode)) { - //TODO If we find a folder, we need to get into it if -R is set - continue; - } - - //Get input file size - i_size = st_buf.st_size; - i_t_size += i_size; - - //TODO Do we want a more verbose output? - fprintf(stdout, "Compressing: %s -> %s\n", pars.input_files[i], output_filename); - - //Lossless optmization requested - if (pars.lossless != 0) { - cclt_optimize(pars.input_files[i], output_filename, pars.exif_copy, pars.input_files[i]); - } else { - //TODO Standard compression requested - //unsigned char* buffer = cclt_decompress(pars.input_files[i], &pars); - //cclt_compress(output_filename, buffer, &pars); - cclt_compress_routine(pars.input_files[i], output_filename, &pars); - } - - //Get output stats - status = stat(output_filename, &st_buf); - if (status != 0) { - //TODO This is not critical - fprintf(stderr, "Failed to get output file stats. Aborting.\n"); - exit(-12); - } - o_size = st_buf.st_size; - o_t_size += o_size; - - fprintf(stdout, "%ld bytes -> %ld bytes [%.2f%%]\n", - (long) i_size, (long) o_size, ((float) o_size - i_size) * 100 / i_size); - - //TODO Perform the required instructions - //TODO Provide complete progress support - //INPUT: pars.input_files[i] | OUTPUT: output_filename - - //Free allocated memory - //TODO Causing segfaults - //free(output_filename); - //free(i_tmp); - } + cclt_start(pars.input_files, pars.input_files_count, pars.output_folder, &pars, &i_t_size, &o_t_size); fprintf(stdout, "Compression completed.\n%ld bytes -> %ld bytes [%.2f%%]\n", (long) i_t_size, (long) o_t_size, ((float) o_t_size - i_t_size) * 100 / i_t_size); diff --git a/src/utils.c b/src/utils.c index e23feac..6e2ca58 100644 --- a/src/utils.c +++ b/src/utils.c @@ -11,7 +11,11 @@ #include #include #include -#include +#include + +#ifdef __linux + #include +#endif #include "utils.h" @@ -31,6 +35,7 @@ cclt_compress_parameters initialize_compression_parameters() { par.exif_copy = 0; par.lossless = 0; par.input_files_count = 0; + par.recursive = 0; return par; } @@ -93,14 +98,17 @@ int mkpath(const char *pathname, mode_t mode) { for(p = parent + strlen(parent); *p != '/' && p != parent; p--); *p = '\0'; /* try make parent directory */ - if(p != parent && mkpath(parent, mode) != 0) - return -1; + if(p != parent && mkpath(parent, mode) != 0) { + return -1; + } /* make this one if parent has been made */ - if(mkdir(pathname, mode) == 0) - return 0; + if(mkdir(pathname, mode) == 0) { + return 0; + } /* if it already exists that is fine */ - if(errno == EEXIST) - return 0; + if (errno == EEXIST) { + return 0; + } return -1; } @@ -186,6 +194,9 @@ cclt_compress_parameters parse_arguments(int argc, char* argv[]) { case 'h': print_help(); break; + case 'R': + parameters.recursive = 1; + break; default: abort(); } @@ -210,4 +221,67 @@ void cclt_compress_routine(char* input, char* output, cclt_compress_parameters* cclt_optimize(output, output, pars->exif_copy, input); } +char** scan_folder(char* dir, int depth) { + int i = 0; + DIR *dp; + struct dirent *entry; + struct stat statbuf; + char** files = (char**) malloc(sizeof(char*)); + if ((dp = opendir(dir)) == NULL) { + fprintf(stderr, "Cannot open %s. Aborting.\n", dir); + exit(-14); + } + chdir(dir); + while ((entry = readdir(dp)) != NULL) { + lstat(entry->d_name, &statbuf); + if (S_ISDIR(statbuf.st_mode)) { + if (strcmp(".", entry->d_name) == 0 || strcmp("..", entry->d_name) == 0) { + continue; + } + files = (char**) realloc(files, sizeof(files) + sizeof(char*)); + printf("QUI\n"); + files[i] = entry->d_name; + i++; + scan_folder(entry->d_name, depth+4); + } + else { + files = (char**) realloc(files, sizeof(files) + sizeof(char*)); + printf("QUI\n"); + files[i] = entry->d_name; + i++; + } + } + + chdir(".."); + closedir(dp); + printf("SEG\n"); + return *files; +} + +void printdir(char *dir, int depth) +{ + DIR *dp; + struct dirent *entry; + struct stat statbuf; + if((dp = opendir(dir)) == NULL) { + fprintf(stderr,"cannot open directory: %s\n", dir); + return; + } + chdir(dir); + while((entry = readdir(dp)) != NULL) { + lstat(entry->d_name,&statbuf); + if(S_ISDIR(statbuf.st_mode)) { + /* Found a directory, but ignore . and .. */ + if(strcmp(".",entry->d_name) == 0 || + strcmp("..",entry->d_name) == 0) + continue; + printf("%*s%s/\n",depth,"",entry->d_name); + /* Recurse at a new indent level */ + printdir(entry->d_name,depth+4); + } + else printf("%*s%s\n",depth,"",entry->d_name); + } + chdir(".."); + closedir(dp); +} diff --git a/src/utils.h b/src/utils.h index 9cce1e7..da8f61f 100644 --- a/src/utils.h +++ b/src/utils.h @@ -21,6 +21,7 @@ typedef struct cclt_compress_parameters { char** input_files; int input_files_count; enum TJSAMP subsample; + int recursive; } cclt_compress_parameters; cclt_compress_parameters initialize_compression_parameters();