Made compression routine a function
This commit is contained in:
parent
3af3101937
commit
1c99cefdf2
185
src/main.c
185
src/main.c
|
@ -7,7 +7,6 @@
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <libexif/exif-data.h>
|
|
||||||
|
|
||||||
#include "lossless.h"
|
#include "lossless.h"
|
||||||
#include "compress.h"
|
#include "compress.h"
|
||||||
|
@ -24,10 +23,114 @@
|
||||||
-R recursive
|
-R recursive
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//TODO Use a general fuction to support folder separators
|
//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;
|
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;
|
errno = 0;
|
||||||
off_t i_t_size = 0, o_t_size = 0;
|
off_t i_t_size = 0, o_t_size = 0;
|
||||||
|
|
||||||
|
@ -82,83 +185,7 @@ int main (int argc, char *argv[]) {
|
||||||
exit(-13);
|
exit(-13);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cclt_start(pars.input_files, pars.input_files_count, pars.output_folder, &pars, &i_t_size, &o_t_size);
|
||||||
//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);
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(stdout, "Compression completed.\n%ld bytes -> %ld bytes [%.2f%%]\n",
|
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);
|
(long) i_t_size, (long) o_t_size, ((float) o_t_size - i_t_size) * 100 / i_t_size);
|
||||||
|
|
88
src/utils.c
88
src/utils.c
|
@ -11,7 +11,11 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <linux/limits.h>
|
#include <dirent.h>
|
||||||
|
|
||||||
|
#ifdef __linux
|
||||||
|
#include <linux/limits.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
@ -31,6 +35,7 @@ cclt_compress_parameters initialize_compression_parameters() {
|
||||||
par.exif_copy = 0;
|
par.exif_copy = 0;
|
||||||
par.lossless = 0;
|
par.lossless = 0;
|
||||||
par.input_files_count = 0;
|
par.input_files_count = 0;
|
||||||
|
par.recursive = 0;
|
||||||
|
|
||||||
return par;
|
return par;
|
||||||
}
|
}
|
||||||
|
@ -93,14 +98,17 @@ int mkpath(const char *pathname, mode_t mode) {
|
||||||
for(p = parent + strlen(parent); *p != '/' && p != parent; p--);
|
for(p = parent + strlen(parent); *p != '/' && p != parent; p--);
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
/* try make parent directory */
|
/* try make parent directory */
|
||||||
if(p != parent && mkpath(parent, mode) != 0)
|
if(p != parent && mkpath(parent, mode) != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
/* make this one if parent has been made */
|
/* make this one if parent has been made */
|
||||||
if(mkdir(pathname, mode) == 0)
|
if(mkdir(pathname, mode) == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
/* if it already exists that is fine */
|
/* if it already exists that is fine */
|
||||||
if(errno == EEXIST)
|
if (errno == EEXIST) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,6 +194,9 @@ cclt_compress_parameters parse_arguments(int argc, char* argv[]) {
|
||||||
case 'h':
|
case 'h':
|
||||||
print_help();
|
print_help();
|
||||||
break;
|
break;
|
||||||
|
case 'R':
|
||||||
|
parameters.recursive = 1;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
@ -210,4 +221,67 @@ void cclt_compress_routine(char* input, char* output, cclt_compress_parameters*
|
||||||
cclt_optimize(output, output, pars->exif_copy, input);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ typedef struct cclt_compress_parameters {
|
||||||
char** input_files;
|
char** input_files;
|
||||||
int input_files_count;
|
int input_files_count;
|
||||||
enum TJSAMP subsample;
|
enum TJSAMP subsample;
|
||||||
|
int recursive;
|
||||||
} cclt_compress_parameters;
|
} cclt_compress_parameters;
|
||||||
|
|
||||||
cclt_compress_parameters initialize_compression_parameters();
|
cclt_compress_parameters initialize_compression_parameters();
|
||||||
|
|
Loading…
Reference in New Issue