Merge try 1
This commit is contained in:
parent
ffb26fb80b
commit
ef72f937b4
|
@ -1,5 +1,5 @@
|
|||
## Caesium Command Line Tools
|
||||
##### CCLT - v0.9.1-beta (build 20160223) - Copyright © Matteo Paonessa, 2016. All Rights Reserved.
|
||||
##### CCLT - v0.9.1-beta (build 20160423) - Copyright © Matteo Paonessa, 2016. All Rights Reserved.
|
||||
|
||||
----------
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
|||
----------
|
||||
|
||||
###### TESTED PLATFORMS
|
||||
* Mac OS X El Capitan (v10.11.1)
|
||||
* Mac OS X El Capitan (v10.11.4)
|
||||
* Arch Linux
|
||||
* Ubuntu 14.04.2
|
||||
|
||||
|
@ -48,6 +48,7 @@ $ caesiumclt -l -R -o ~/output/ ~/Pictures
|
|||
|
||||
###### TODO
|
||||
* Code cleaning
|
||||
* Keep folder structure
|
||||
|
||||
----------
|
||||
|
||||
|
@ -64,7 +65,8 @@ Check the [Commits](https://github.com/Lymphatus/CaesiumCLT/commits/master) for
|
|||
----------
|
||||
|
||||
###### RESOURCES
|
||||
* CaesiumCLT website - [http://saerasoft.com/caesium](http://saerasoft.com/caesium/clt)
|
||||
* Caesium website - [http://saerasoft.com/caesium](http://saerasoft.com/caesium)
|
||||
* CCLT Git Repository - [https://github.com/Lymphatus/CaesiumCLT](https://github.com/Lymphatus/CaesiumCLT)
|
||||
* CaesiumCLT Git Repository - [https://github.com/Lymphatus/CaesiumCLT](https://github.com/Lymphatus/CaesiumCLT)
|
||||
* Author website - SaeraSoft - [http://saerasoft.com](http://saerasoft.com)
|
||||
* Twitter - [Matteo Paonessa](https://twitter.com/MatteoPaonessa)
|
||||
|
|
|
@ -47,17 +47,51 @@ cclt_parameters initialize_compression_parameters() {
|
|||
return par;
|
||||
}
|
||||
|
||||
cclt_parameters parse_arguments(int argc, char* argv[]) {
|
||||
void validate_parameters(cclt_compress_parameters* pars) {
|
||||
//Either -l or -q must be set but not together
|
||||
if (!((pars->lossless == 1) ^ (pars->quality > 0))) {
|
||||
//Both or none are set
|
||||
if (pars->lossless == 1 && pars->quality > 0) {
|
||||
fprintf(stderr, "-l option can't be used with -q. Either use one or the other. Aborting.\n");
|
||||
exit(-1);
|
||||
} else if (pars->lossless == 0 && pars->quality <= 0) {
|
||||
fprintf(stderr, "Either -l or -q must be set. Aborting.\n");
|
||||
print_help();
|
||||
exit(-2);
|
||||
}
|
||||
} else {
|
||||
//One of them is set
|
||||
//If -q is set check it is within the 1-100 range
|
||||
if (!(pars->quality >= 1 && pars->quality <= 100) && pars->lossless == 0) {
|
||||
fprintf(stderr, "Quality must be within a [1-100] range. Aborting.\n");
|
||||
exit(-3);
|
||||
}
|
||||
}
|
||||
|
||||
//Check if you set the input files
|
||||
if (pars->input_files_count == 0) {
|
||||
fprintf(stderr, "No input files. Aborting.\n");
|
||||
exit(-9);
|
||||
}
|
||||
|
||||
//Check if the output folder exists, otherwise create it
|
||||
if (pars->output_folder == NULL) {
|
||||
fprintf(stderr, "No -o option pointing to the destination folder. Aborting.\n");
|
||||
exit(-4);
|
||||
}
|
||||
}
|
||||
|
||||
cclt_compress_parameters parse_arguments(int argc, char* argv[]) {
|
||||
|
||||
//Initialize default params
|
||||
cclt_parameters parameters = initialize_compression_parameters();
|
||||
cclt_compress_parameters parameters = initialize_compression_parameters();
|
||||
int c;
|
||||
|
||||
while (optind < argc) {
|
||||
if ((c = getopt (argc, argv, "q:velo:s:hR")) != -1) {
|
||||
switch (c) {
|
||||
case 'v':
|
||||
printf("CaesiumCLT - Caesium Command Line Tools - Version %s (Build: %d)\n", APP_VERSION, BUILD);
|
||||
printf("%s (Build: %d)\n", APP_VERSION, BUILD);
|
||||
exit(0);
|
||||
break;
|
||||
case '?':
|
||||
|
@ -77,13 +111,13 @@ cclt_parameters parse_arguments(int argc, char* argv[]) {
|
|||
fprintf(stderr, "Parameter expected.\n");
|
||||
break;
|
||||
case 'q':
|
||||
parameters.jpeg.quality = string_to_int(optarg);
|
||||
parameters.quality = string_to_int(optarg);
|
||||
break;
|
||||
case 'e':
|
||||
parameters.jpeg.exif_copy = 1;
|
||||
parameters.exif_copy = 1;
|
||||
break;
|
||||
case 'l':
|
||||
parameters.jpeg.lossless = 1;
|
||||
parameters.lossless = 1;
|
||||
break;
|
||||
case 'o':
|
||||
parameters.output_folder = optarg;
|
||||
|
@ -112,7 +146,6 @@ cclt_parameters parse_arguments(int argc, char* argv[]) {
|
|||
printf("[WARNING] Folder found, skipping all other inputs.\n");
|
||||
}
|
||||
scan_folder(¶meters, argv[optind], parameters.recursive);
|
||||
//parameters.input_files = scan_folder(argv[optind], ¶meters.input_files_count, parameters.recursive);
|
||||
return parameters;
|
||||
} else {
|
||||
parameters.input_files[i] = (char*) malloc (strlen(argv[optind]) * sizeof(char)); //TODO Necessary??
|
||||
|
@ -125,25 +158,106 @@ cclt_parameters parse_arguments(int argc, char* argv[]) {
|
|||
}
|
||||
}
|
||||
|
||||
//Check if all parameters are poperly set
|
||||
validate_parameters(¶meters);
|
||||
|
||||
return parameters;
|
||||
}
|
||||
|
||||
int cclt_compress_routine(char* input, char* output, cclt_parameters* pars) {
|
||||
int cclt_compress_routine(char* input, char* output, cclt_compress_parameters* pars) {
|
||||
//Detect which image type are we compressing
|
||||
enum image_type type = detect_image_type(input);
|
||||
if (type == JPEG && pars->jpeg.lossless == 0) {
|
||||
cclt_jpeg_compress(output, cclt_jpeg_decompress(input, &pars->jpeg), &pars->jpeg);
|
||||
cclt_jpeg_optimize(output, output, pars->jpeg.exif_copy, input);
|
||||
} else if (type == JPEG && pars->jpeg.lossless != 0) {
|
||||
cclt_jpeg_optimize(input, output, pars->jpeg.exif_copy, input);
|
||||
} else if (type == PNG) {
|
||||
//Give a message to the user if he set a quality for PNGs
|
||||
if (pars->jpeg.quality != 0) {
|
||||
printf("PNG file, ignoring quality parameter.\n");
|
||||
|
||||
if (type == JPEG) {
|
||||
//Lossy processing just uses the compression method before optimizing
|
||||
if (!pars->lossless) {
|
||||
cclt_jpeg_compress(output, cclt_jpeg_decompress(input, pars), pars);
|
||||
}
|
||||
cclt_png_optimize(input, output, &pars->png);
|
||||
//Optimize
|
||||
cclt_jpeg_optimize(output, output, pars->exif_copy, input);
|
||||
} else if (type == PNG) {
|
||||
cclt_png_optimize(input, output);
|
||||
} else {
|
||||
printf("Unknown file type.\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cclt_start(cclt_compress_parameters* pars, off_t* i_t_size, off_t* o_t_size) {
|
||||
|
||||
struct stat st_buf;
|
||||
int i = 0;
|
||||
|
||||
//Creates the output folder (which will always be needed)
|
||||
if (mkpath(pars->output_folder, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == -1) {
|
||||
if (errno != EEXIST) {
|
||||
fprintf(stderr, "Failed to create output directory. Aborting.\n");
|
||||
exit(-5);
|
||||
}
|
||||
}
|
||||
|
||||
while (i < pars->input_files_count) {
|
||||
|
||||
off_t i_size, o_size;
|
||||
int status; //Pointer for stat() call
|
||||
|
||||
char* output_filename = (char*) malloc ((strlen(pars->output_folder) + 1) * sizeof(char));
|
||||
|
||||
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(basename(pars->input_files[i]))) * sizeof(char));
|
||||
output_filename = strcat(output_filename, basename(pars->input_files[i]));
|
||||
|
||||
//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);
|
||||
}
|
||||
|
||||
//Check if we ran into a folder
|
||||
//TODO Check symlinks too
|
||||
if (is_directory(pars->input_files[i])) {
|
||||
//Folder found, but we don't need it here
|
||||
i++;
|
||||
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);
|
||||
|
||||
int routine = cclt_compress_routine(pars->input_files[i], output_filename, pars);
|
||||
if (routine == -1) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
//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, "%s -> %s [%.2f%%]\n",
|
||||
get_human_size(i_size),
|
||||
get_human_size(o_size),
|
||||
((float) o_size - i_size) * 100 / i_size);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
78
src/main.c
78
src/main.c
|
@ -28,84 +28,6 @@
|
|||
|
||||
//TODO If the output is INSIDE the folder we are passing as input, ignore it or we're gonna go in a infinite loop
|
||||
|
||||
void cclt_start(cclt_parameters* pars, off_t* i_t_size, off_t* o_t_size) {
|
||||
|
||||
struct stat st_buf;
|
||||
int i = 0;
|
||||
|
||||
char** input_files = pars->input_files;
|
||||
int n = pars->input_files_count;
|
||||
char* output_folder = pars->output_folder;
|
||||
|
||||
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) + 1) * sizeof(char));
|
||||
|
||||
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(basename(input_files[i]))) * sizeof(char));
|
||||
output_filename = strcat(output_filename, basename(input_files[i]));
|
||||
|
||||
//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 (is_directory(input_files[i])) {
|
||||
//Folder found, but we don't need it here
|
||||
i++;
|
||||
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);
|
||||
|
||||
int routine = cclt_compress_routine(input_files[i], output_filename, pars);
|
||||
if (routine == -1) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
//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, "%s -> %s [%.2f%%]\n",
|
||||
get_human_size(i_size), get_human_size(o_size), ((float) o_size - i_size) * 100 / i_size);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[]) {
|
||||
errno = 0;
|
||||
off_t i_t_size = 0, o_t_size = 0;
|
||||
|
|
Loading…
Reference in New Issue