The output uses human readable sizes
This commit is contained in:
parent
c20b2e98f7
commit
7e72b94eb8
32
README.md
32
README.md
|
@ -22,15 +22,45 @@ See INSTALL for more details.
|
||||||
|
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
###### USAGE EXAMPLES
|
||||||
|
```
|
||||||
|
$ caesiumclt -l -o ~/output/ ~/image.jpg
|
||||||
|
```
|
||||||
|
Losslessly compress ```image1.jpg```, located in the ```home``` directory, into a folder called ```output```
|
||||||
|
|
||||||
|
```
|
||||||
|
$ caesiumclt -q 80 -o ~/output/ ~/image.jpg
|
||||||
|
```
|
||||||
|
Compress ```image1.jpg```, located in the ```home``` directory, into a folder called ```output``` with lossy compression and quality set to 80
|
||||||
|
|
||||||
|
```
|
||||||
|
$ caesiumclt -l -e -o ~/output/ ~/image.jpg
|
||||||
|
```
|
||||||
|
Losslessly compress ```image1.jpg```, located in the ```home``` directory, into a folder called ```output``` and keeps EXIF metadata
|
||||||
|
|
||||||
|
```
|
||||||
|
$ caesiumclt -l -R -o ~/output/ ~/Pictures
|
||||||
|
```
|
||||||
|
Losslessly compress ```Pictures``` folder and subfolders, located in the ```home``` directory, into a folder called ```output```
|
||||||
|
|
||||||
|
```
|
||||||
|
$ caesiumclt -q 80 -s 50% -o ~/output/ ~/image1.jpg
|
||||||
|
```
|
||||||
|
Compress with quality 80 and resize at 50% ```image1.jpg```, located in the ```home``` directory, into a folder called ```output```
|
||||||
|
|
||||||
|
----------
|
||||||
|
|
||||||
###### TODO
|
###### TODO
|
||||||
* GIF support?
|
|
||||||
* Code cleaning
|
* Code cleaning
|
||||||
|
* Folder structure support
|
||||||
|
|
||||||
----------
|
----------
|
||||||
|
|
||||||
###### CHANGELOG
|
###### CHANGELOG
|
||||||
* 0.9.1-beta - Initial development stage
|
* 0.9.1-beta - Initial development stage
|
||||||
|
|
||||||
|
Check the [Commits](https://github.com/Lymphatus/CaesiumCLT/commits/master) for a detailed list of changes.
|
||||||
|
|
||||||
----------
|
----------
|
||||||
|
|
||||||
###### RESOURCES
|
###### RESOURCES
|
||||||
|
|
|
@ -120,8 +120,6 @@ int cclt_compress_routine(char* input, char* output, cclt_compress_parameters* p
|
||||||
cclt_jpeg_optimize(input, output, pars->exif_copy, input);
|
cclt_jpeg_optimize(input, output, pars->exif_copy, input);
|
||||||
} else if (type == PNG) {
|
} else if (type == PNG) {
|
||||||
cclt_png_optimize(input, output);
|
cclt_png_optimize(input, output);
|
||||||
} else if (type == GIF) {
|
|
||||||
printf("GIF detected. Not implemented yet.\n");
|
|
||||||
} else {
|
} else {
|
||||||
printf("Unknown file type.\n");
|
printf("Unknown file type.\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
|
12
src/main.c
12
src/main.c
|
@ -76,6 +76,7 @@ void cclt_start(char** input_files, int n, char* output_folder, cclt_compress_pa
|
||||||
//TODO Check symlinks too
|
//TODO Check symlinks too
|
||||||
if (isDirectory(input_files[i])) {
|
if (isDirectory(input_files[i])) {
|
||||||
//Folder found, but we don't need it here
|
//Folder found, but we don't need it here
|
||||||
|
printf("Folder found\n");
|
||||||
i++;
|
i++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -103,8 +104,8 @@ void cclt_start(char** input_files, int n, char* output_folder, cclt_compress_pa
|
||||||
o_size = st_buf.st_size;
|
o_size = st_buf.st_size;
|
||||||
*(o_t_size) += o_size;
|
*(o_t_size) += o_size;
|
||||||
|
|
||||||
fprintf(stdout, "%ld bytes -> %ld bytes [%.2f%%]\n",
|
fprintf(stdout, "%s -> %s [%.2f%%]\n",
|
||||||
(long) i_size, (long) o_size, ((float) o_size - i_size) * 100 / i_size);
|
get_human_size(i_size), get_human_size(o_size), ((float) o_size - i_size) * 100 / i_size);
|
||||||
|
|
||||||
//TODO Provide complete progress support
|
//TODO Provide complete progress support
|
||||||
i++;
|
i++;
|
||||||
|
@ -171,8 +172,11 @@ int main (int argc, char *argv[]) {
|
||||||
//We need the file list right here
|
//We need the file list right here
|
||||||
cclt_start(pars.input_files, pars.input_files_count, pars.output_folder, &pars, &i_t_size, &o_t_size);
|
cclt_start(pars.input_files, pars.input_files_count, pars.output_folder, &pars, &i_t_size, &o_t_size);
|
||||||
|
|
||||||
fprintf(stdout, "-------------------------------\nCompression completed.\n%ld bytes -> %ld bytes [%.2f%% | %ld bytes]\n",
|
fprintf(stdout, "-------------------------------\nCompression completed.\n%s -> %s [%.2f%% | %s]\n",
|
||||||
(long) i_t_size, (long) o_t_size, ((float) o_t_size - i_t_size) * 100 / i_t_size, (long) (o_t_size - i_t_size));
|
get_human_size((long) i_t_size),
|
||||||
|
get_human_size((long) o_t_size),
|
||||||
|
((float) o_t_size - i_t_size) * 100 / i_t_size,
|
||||||
|
get_human_size(((long) o_t_size - i_t_size)));
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
29
src/utils.c
29
src/utils.c
|
@ -10,6 +10,7 @@
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#ifdef __linux
|
#ifdef __linux
|
||||||
#include <linux/limits.h>
|
#include <linux/limits.h>
|
||||||
|
@ -50,8 +51,8 @@ void print_help() {
|
||||||
"\t-o\tcompress to custom folder\n"
|
"\t-o\tcompress to custom folder\n"
|
||||||
"\t-l\tuse lossless optimization\n"
|
"\t-l\tuse lossless optimization\n"
|
||||||
"\t-s\tscale to value, expressed as percentage (e.g. 20%%) [Only 1/2^n allowed]\n"
|
"\t-s\tscale to value, expressed as percentage (e.g. 20%%) [Only 1/2^n allowed]\n"
|
||||||
//TODO Remove this warning
|
|
||||||
"\t-R\tif input is a folder, scan subfolders too\n"
|
"\t-R\tif input is a folder, scan subfolders too\n"
|
||||||
|
//TODO Remove this warning
|
||||||
"\t-S\tkeep the folder structure [Not active yet]\n"
|
"\t-S\tkeep the folder structure [Not active yet]\n"
|
||||||
"\t-h\tdisplay this help and exit\n"
|
"\t-h\tdisplay this help and exit\n"
|
||||||
"\t-v\toutput version information and exit\n\n");
|
"\t-v\toutput version information and exit\n\n");
|
||||||
|
@ -153,6 +154,7 @@ char** scan_folder(char* basedir, int* n, int recur) {
|
||||||
}
|
}
|
||||||
|
|
||||||
enum image_type detect_image_type(char* path) {
|
enum image_type detect_image_type(char* path) {
|
||||||
|
//Open the file
|
||||||
FILE* fp;
|
FILE* fp;
|
||||||
unsigned char* type_buffer = valloc(2);
|
unsigned char* type_buffer = valloc(2);
|
||||||
|
|
||||||
|
@ -162,14 +164,15 @@ enum image_type detect_image_type(char* path) {
|
||||||
fprintf(stderr, "Cannot open input file for type detection. Aborting.\n");
|
fprintf(stderr, "Cannot open input file for type detection. Aborting.\n");
|
||||||
exit(-14);
|
exit(-14);
|
||||||
}
|
}
|
||||||
|
//Read enough bytes
|
||||||
if (fread(type_buffer, 1, 2, fp) < 2) {
|
if (fread(type_buffer, 1, 2, fp) < 2) {
|
||||||
fprintf(stderr, "Cannot read file type. Aborting.\n");
|
fprintf(stderr, "Cannot read file type. Aborting.\n");
|
||||||
exit(-15);
|
exit(-15);
|
||||||
}
|
}
|
||||||
|
//We don't need it anymore
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
|
//Check the bytes against the JPEG and PNG specs
|
||||||
if (((int) type_buffer[0] == 0xFF) && ((int) type_buffer[1] == 0xD8)) {
|
if (((int) type_buffer[0] == 0xFF) && ((int) type_buffer[1] == 0xD8)) {
|
||||||
free(type_buffer);
|
free(type_buffer);
|
||||||
return JPEG;
|
return JPEG;
|
||||||
|
@ -185,4 +188,24 @@ int isDirectory(const char *file_path) {
|
||||||
struct stat s;
|
struct stat s;
|
||||||
stat(file_path, &s);
|
stat(file_path, &s);
|
||||||
return S_ISDIR(s.st_mode);
|
return S_ISDIR(s.st_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* get_human_size(long size) {
|
||||||
|
//We should not get more than TB images
|
||||||
|
char* unit[5] = {"B", "KB", "MB", "GB", "TB"};
|
||||||
|
//Index of the array containing the correct unit
|
||||||
|
double order = floor(log2(labs(size)) / 10);
|
||||||
|
//Alloc enough size for the final string
|
||||||
|
char* final = (char*) malloc(((int) (floor(log10(labs(size))) + 4)) * sizeof(char));
|
||||||
|
|
||||||
|
//If the order exceeds 4, something is fishy
|
||||||
|
if (order > 4) {
|
||||||
|
fprintf(stderr, "Do you really have such a huge file?\n");
|
||||||
|
order = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Copy the formatted string into the buffer
|
||||||
|
sprintf(final, "%.2f %s", size / (pow(1024, order)), unit[(int)order]);
|
||||||
|
//And return it
|
||||||
|
return final;
|
||||||
}
|
}
|
|
@ -28,7 +28,6 @@ typedef struct cclt_compress_parameters {
|
||||||
enum image_type {
|
enum image_type {
|
||||||
JPEG,
|
JPEG,
|
||||||
PNG,
|
PNG,
|
||||||
GIF,
|
|
||||||
UNKN,
|
UNKN,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -39,5 +38,6 @@ int mkpath(const char *pathname, mode_t mode);
|
||||||
enum image_type detect_image_type(char* path);
|
enum image_type detect_image_type(char* path);
|
||||||
int isDirectory(const char *file_path);
|
int isDirectory(const char *file_path);
|
||||||
char** scan_folder(char* basedir, int* n, int recur);
|
char** scan_folder(char* basedir, int* n, int recur);
|
||||||
|
char* get_human_size(long size);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue