Code style adjustments
This commit is contained in:
parent
9326392bb3
commit
0ac1a50f1e
|
@ -18,7 +18,8 @@
|
|||
#include "png.h"
|
||||
#include "error.h"
|
||||
|
||||
void initialize_jpeg_parameters(cclt_parameters* par) {
|
||||
void initialize_jpeg_parameters(cclt_parameters* par)
|
||||
{
|
||||
par->jpeg.quality = 0;
|
||||
par->jpeg.width = 0;
|
||||
par->jpeg.height = 0;
|
||||
|
@ -28,7 +29,8 @@ void initialize_jpeg_parameters(cclt_parameters* par) {
|
|||
par->jpeg.lossless = false;
|
||||
}
|
||||
|
||||
void initialize_png_parameters(cclt_parameters* par) {
|
||||
void initialize_png_parameters(cclt_parameters* par)
|
||||
{
|
||||
par->png.iterations = 10;
|
||||
par->png.iterations_large = 5;
|
||||
par->png.block_split_strategy = 4;
|
||||
|
@ -37,7 +39,8 @@ void initialize_png_parameters(cclt_parameters* par) {
|
|||
par->png.auto_filter_strategy = 1;
|
||||
}
|
||||
|
||||
cclt_parameters initialize_compression_parameters() {
|
||||
cclt_parameters initialize_compression_parameters()
|
||||
{
|
||||
cclt_parameters par;
|
||||
|
||||
initialize_jpeg_parameters(&par);
|
||||
|
@ -52,7 +55,8 @@ cclt_parameters initialize_compression_parameters() {
|
|||
return par;
|
||||
}
|
||||
|
||||
void validate_parameters(cclt_parameters* pars) {
|
||||
void validate_parameters(cclt_parameters* pars)
|
||||
{
|
||||
//Either -l or -q must be set but not together
|
||||
if (!((pars->jpeg.lossless) ^ (pars->jpeg.quality > 0))) {
|
||||
//Both or none are set
|
||||
|
@ -80,59 +84,58 @@ void validate_parameters(cclt_parameters* pars) {
|
|||
}
|
||||
}
|
||||
|
||||
cclt_parameters parse_arguments(int argc, char* argv[]) {
|
||||
cclt_parameters parse_arguments(int argc, char* argv[])
|
||||
{
|
||||
|
||||
//Initialize default params
|
||||
cclt_parameters parameters = initialize_compression_parameters();
|
||||
int c;
|
||||
|
||||
while (optind < argc) {
|
||||
if ((c = getopt (argc, argv, "q:velo:s:hR")) != -1) {
|
||||
if ((c = getopt(argc, argv, "q:velo:s:hR")) != -1) {
|
||||
switch (c) {
|
||||
case 'v':
|
||||
printf("%s-%d\n", APP_VERSION, BUILD);
|
||||
exit(0);
|
||||
case '?':
|
||||
if (optopt == 'q' || optopt == 'o' || optopt == 's') {
|
||||
trigger_error(6, true, optopt);
|
||||
}
|
||||
else if (isprint(optopt)) {
|
||||
trigger_error(100, false, optopt);
|
||||
}
|
||||
else {
|
||||
trigger_error(101, false, optopt);
|
||||
}
|
||||
break;
|
||||
case ':':
|
||||
trigger_error(102, false);
|
||||
break;
|
||||
case 'q':
|
||||
parameters.jpeg.quality = string_to_int(optarg);
|
||||
break;
|
||||
case 'e':
|
||||
parameters.jpeg.exif_copy = true;
|
||||
break;
|
||||
case 'l':
|
||||
parameters.jpeg.lossless = true;
|
||||
break;
|
||||
case 'o':
|
||||
parameters.output_folder = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
print_help();
|
||||
break;
|
||||
case 'R':
|
||||
parameters.recursive = true;
|
||||
break;
|
||||
case 'S':
|
||||
parameters.structure = true;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
case 'v':
|
||||
printf("%s-%d\n", APP_VERSION, BUILD);
|
||||
exit(0);
|
||||
case '?':
|
||||
if (optopt == 'q' || optopt == 'o' || optopt == 's') {
|
||||
trigger_error(6, true, optopt);
|
||||
} else if (isprint(optopt)) {
|
||||
trigger_error(100, false, optopt);
|
||||
} else {
|
||||
trigger_error(101, false, optopt);
|
||||
}
|
||||
break;
|
||||
case ':':
|
||||
trigger_error(102, false);
|
||||
break;
|
||||
case 'q':
|
||||
parameters.jpeg.quality = string_to_int(optarg);
|
||||
break;
|
||||
case 'e':
|
||||
parameters.jpeg.exif_copy = true;
|
||||
break;
|
||||
case 'l':
|
||||
parameters.jpeg.lossless = true;
|
||||
break;
|
||||
case 'o':
|
||||
parameters.output_folder = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
print_help();
|
||||
break;
|
||||
case 'R':
|
||||
parameters.recursive = true;
|
||||
break;
|
||||
case 'S':
|
||||
parameters.structure = true;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
} else {
|
||||
int i = 0;
|
||||
parameters.input_files = (char**) malloc ((argc - optind) * sizeof (char*));
|
||||
parameters.input_files = (char**)malloc((argc - optind) * sizeof(char*));
|
||||
while (optind < argc) {
|
||||
if (is_directory(argv[optind])) {
|
||||
if (i != 0) {
|
||||
|
@ -144,7 +147,7 @@ cclt_parameters parse_arguments(int argc, char* argv[]) {
|
|||
scan_folder(¶meters, argv[optind], parameters.recursive);
|
||||
return parameters;
|
||||
} else {
|
||||
parameters.input_files[i] = (char*) malloc (strlen(argv[optind]) * sizeof(char)); //TODO Necessary??
|
||||
parameters.input_files[i] = (char*)malloc(strlen(argv[optind]) * sizeof(char)); //TODO Necessary??
|
||||
parameters.input_files[i] = argv[optind];
|
||||
i++;
|
||||
parameters.input_files_count = i;
|
||||
|
@ -160,10 +163,11 @@ cclt_parameters parse_arguments(int argc, char* argv[]) {
|
|||
return parameters;
|
||||
}
|
||||
|
||||
int cclt_compress_routine(char* input, char* output, cclt_parameters* pars) {
|
||||
int cclt_compress_routine(char* input, char* output, cclt_parameters* pars)
|
||||
{
|
||||
//Detect which image type are we compressing
|
||||
enum image_type type = detect_image_type(input);
|
||||
char* exif_orig = (char*) malloc(strlen(input) * sizeof(char));
|
||||
char* exif_orig = (char*)malloc(strlen(input) * sizeof(char));
|
||||
strcpy(exif_orig, input);
|
||||
|
||||
if (type == JPEG) {
|
||||
|
@ -187,8 +191,8 @@ int cclt_compress_routine(char* input, char* output, cclt_parameters* pars) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void cclt_start(cclt_parameters* pars, off_t* i_t_size, off_t* o_t_size) {
|
||||
|
||||
void cclt_start(cclt_parameters* pars, off_t* i_t_size, off_t* o_t_size)
|
||||
{
|
||||
struct stat st_buf;
|
||||
int i = 0;
|
||||
|
||||
|
@ -204,7 +208,7 @@ void cclt_start(cclt_parameters* pars, off_t* i_t_size, off_t* o_t_size) {
|
|||
off_t i_size, o_size;
|
||||
int status; //Pointer for stat() call
|
||||
|
||||
char* output_filename = (char*) malloc ((strlen(pars->output_folder) + 1) * sizeof(char));
|
||||
char* output_filename = (char*)malloc((strlen(pars->output_folder) + 1) * sizeof(char));
|
||||
|
||||
strcpy(output_filename, pars->output_folder);
|
||||
|
||||
|
@ -222,10 +226,10 @@ void cclt_start(cclt_parameters* pars, off_t* i_t_size, off_t* o_t_size) {
|
|||
trigger_error(11, true, pars->input_files[i]);
|
||||
}
|
||||
|
||||
//Check if we ran into a folder
|
||||
//TODO Check symlinks too
|
||||
//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
|
||||
//Folder found, but we don't need it here
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
@ -236,10 +240,10 @@ void cclt_start(cclt_parameters* pars, off_t* i_t_size, off_t* o_t_size) {
|
|||
|
||||
//TODO Do we want a more verbose output?
|
||||
fprintf(stdout, "(%d/%d) %s -> %s\n",
|
||||
i + 1,
|
||||
pars->input_files_count,
|
||||
pars->input_files[i],
|
||||
output_filename);
|
||||
i + 1,
|
||||
pars->input_files_count,
|
||||
pars->input_files[i],
|
||||
output_filename);
|
||||
|
||||
int routine = cclt_compress_routine(pars->input_files[i], output_filename, pars);
|
||||
if (routine == -1) {
|
||||
|
@ -257,11 +261,10 @@ void cclt_start(cclt_parameters* pars, off_t* i_t_size, off_t* o_t_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);
|
||||
get_human_size(i_size),
|
||||
get_human_size(o_size),
|
||||
((float)o_size - i_size) * 100 / i_size);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
229
src/error.c
229
src/error.c
|
@ -11,110 +11,137 @@
|
|||
|
||||
#define parse_error_level(level) ((level) ? "ERROR" : "WARNING")
|
||||
|
||||
void trigger_error(int code, bool is_critical, ...) {
|
||||
va_list args;
|
||||
va_start(args, is_critical);
|
||||
void trigger_error(int code, bool is_critical, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, is_critical);
|
||||
|
||||
fprintf(stderr, "%s - %d: ",
|
||||
parse_error_level(is_critical),
|
||||
code);
|
||||
fprintf(stderr, "%s - %d: ",
|
||||
parse_error_level(is_critical),
|
||||
code);
|
||||
|
||||
switch (code) {
|
||||
case 1:
|
||||
fprintf(stderr,
|
||||
"-l option can't be used with -q. Either use one or the other.");
|
||||
break;
|
||||
case 2:
|
||||
fprintf(stderr,
|
||||
"Either -l or -q must be set.");
|
||||
break;
|
||||
case 3:
|
||||
fprintf(stderr,
|
||||
"Quality must be within a [1-100] range.");
|
||||
break;
|
||||
case 4:
|
||||
fprintf(stderr,
|
||||
"No -o option pointing to the destination folder.");
|
||||
break;
|
||||
case 5:
|
||||
fprintf(stderr,
|
||||
"Failed to create output directory. Permission issue?");
|
||||
break;
|
||||
case 6:
|
||||
vfprintf(stderr,
|
||||
"Option -%c requires an argument.", args);
|
||||
break;
|
||||
case 9:
|
||||
fprintf(stderr,
|
||||
"No input files.");
|
||||
break;
|
||||
case 11:
|
||||
vfprintf(stderr,
|
||||
"Failed to get input file stats: %s", args);
|
||||
break;
|
||||
case 12:
|
||||
vfprintf(stderr,
|
||||
"Failed to get output file stats: %s", args);
|
||||
break;
|
||||
case 13:
|
||||
vfprintf(stderr,
|
||||
"Failed to open file (markers): %s", args);
|
||||
break;
|
||||
case 16:
|
||||
vfprintf(stderr,
|
||||
"Failed to open PNG file: %s", args);
|
||||
break;
|
||||
case 17:
|
||||
fprintf(stderr,
|
||||
"Error while optimizing PNG.");
|
||||
break;
|
||||
case 18:
|
||||
vfprintf(stderr,
|
||||
"Error while writing PNG: %s", args);
|
||||
case 20:
|
||||
fprintf(stderr,
|
||||
"Found folder along with input files.");
|
||||
case 100:
|
||||
vfprintf(stderr,
|
||||
"Unknown option `-%c'.", args);
|
||||
break;
|
||||
case 101:
|
||||
vfprintf(stderr,
|
||||
"Unknown option character `\\x%x'.", args);
|
||||
break;
|
||||
case 102:
|
||||
fprintf(stderr,
|
||||
"Parameter expected.");
|
||||
break;
|
||||
case 103:
|
||||
fprintf(stderr,
|
||||
"Folder found, skipping all other inputs.");
|
||||
break;
|
||||
case 104:
|
||||
vfprintf(stderr,
|
||||
"Unknown file type: %s", args);
|
||||
break;
|
||||
case 105:
|
||||
vfprintf(stderr,
|
||||
"Failed to open file (input): %s", args);
|
||||
break;
|
||||
case 106:
|
||||
vfprintf(stderr,
|
||||
"Failed to open file (output): %s", args);
|
||||
break;
|
||||
default:
|
||||
//Every unlisted code is critical
|
||||
is_critical = true;
|
||||
fprintf(stderr,
|
||||
"Cs-137 spreading out. Good luck.");
|
||||
break;
|
||||
}
|
||||
switch (code) {
|
||||
case 1:
|
||||
fprintf(stderr,
|
||||
"-l option can't be used with -q. Either use one or the other.");
|
||||
break;
|
||||
case 2:
|
||||
fprintf(stderr,
|
||||
"Either -l or -q must be set.");
|
||||
break;
|
||||
case 3:
|
||||
fprintf(stderr,
|
||||
"Quality must be within a [1-100] range.");
|
||||
break;
|
||||
case 4:
|
||||
fprintf(stderr,
|
||||
"No -o option pointing to the destination folder.");
|
||||
break;
|
||||
case 5:
|
||||
fprintf(stderr,
|
||||
"Failed to create output directory. Permission issue?");
|
||||
break;
|
||||
case 6:
|
||||
vfprintf(stderr,
|
||||
"Option -%c requires an argument.", args);
|
||||
break;
|
||||
case 7:
|
||||
fprintf(stderr,
|
||||
"No digits were found for -q option.");
|
||||
break;
|
||||
case 8:
|
||||
fprintf(stderr,
|
||||
"Cannot parse quality value.");
|
||||
break;
|
||||
case 9:
|
||||
fprintf(stderr,
|
||||
"No input files.");
|
||||
break;
|
||||
case 11:
|
||||
vfprintf(stderr,
|
||||
"Failed to get input file stats: %s", args);
|
||||
break;
|
||||
case 12:
|
||||
vfprintf(stderr,
|
||||
"Failed to get output file stats: %s", args);
|
||||
break;
|
||||
case 13:
|
||||
vfprintf(stderr,
|
||||
"Failed to open file (markers): %s", args);
|
||||
break;
|
||||
case 14:
|
||||
vfprintf(stderr,
|
||||
"Cannot open input file for type detection: %s", args);
|
||||
break;
|
||||
case 15:
|
||||
vfprintf(stderr,
|
||||
"Cannot read file type: %s", args);
|
||||
break;
|
||||
case 16:
|
||||
vfprintf(stderr,
|
||||
"Failed to open PNG file: %s", args);
|
||||
break;
|
||||
case 17:
|
||||
fprintf(stderr,
|
||||
"Error while optimizing PNG.");
|
||||
break;
|
||||
case 18:
|
||||
vfprintf(stderr,
|
||||
"Error while writing PNG: %s", args);
|
||||
break;
|
||||
case 19:
|
||||
vfprintf(stderr,
|
||||
"Failed to open folder: %s", args);
|
||||
break;
|
||||
case 20:
|
||||
fprintf(stderr,
|
||||
"Found folder along with input files.");
|
||||
break;
|
||||
case 21:
|
||||
fprintf(stderr,
|
||||
"Do you really have such a huge file?");
|
||||
break;
|
||||
case 100:
|
||||
vfprintf(stderr,
|
||||
"Unknown option `-%c'.", args);
|
||||
break;
|
||||
case 101:
|
||||
vfprintf(stderr,
|
||||
"Unknown option character `\\x%x'.", args);
|
||||
break;
|
||||
case 102:
|
||||
fprintf(stderr,
|
||||
"Parameter expected.");
|
||||
break;
|
||||
case 103:
|
||||
fprintf(stderr,
|
||||
"Folder found, skipping all other inputs.");
|
||||
break;
|
||||
case 104:
|
||||
vfprintf(stderr,
|
||||
"Unknown file type: %s", args);
|
||||
break;
|
||||
case 105:
|
||||
vfprintf(stderr,
|
||||
"Failed to open file (input): %s", args);
|
||||
break;
|
||||
case 106:
|
||||
vfprintf(stderr,
|
||||
"Failed to open file (output): %s", args);
|
||||
break;
|
||||
default:
|
||||
//Every unlisted code is critical
|
||||
is_critical = true;
|
||||
fprintf(stderr,
|
||||
"Cs-137 spreading out. Good luck.");
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
va_end(args);
|
||||
va_end(args);
|
||||
|
||||
if (is_critical) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (is_critical) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
|
90
src/jpeg.c
90
src/jpeg.c
|
@ -13,7 +13,8 @@
|
|||
|
||||
//TODO Error handling
|
||||
|
||||
struct jpeg_decompress_struct cclt_get_markers(char* input) {
|
||||
struct jpeg_decompress_struct cclt_get_markers(char* input)
|
||||
{
|
||||
FILE* fp;
|
||||
struct jpeg_decompress_struct einfo;
|
||||
struct jpeg_error_mgr eerr;
|
||||
|
@ -21,7 +22,7 @@ struct jpeg_decompress_struct cclt_get_markers(char* input) {
|
|||
|
||||
jpeg_create_decompress(&einfo);
|
||||
|
||||
//Open the input file
|
||||
//Open the input file
|
||||
fp = fopen(input, "r");
|
||||
|
||||
//Check for errors
|
||||
|
@ -45,7 +46,8 @@ struct jpeg_decompress_struct cclt_get_markers(char* input) {
|
|||
return einfo;
|
||||
}
|
||||
|
||||
int cclt_jpeg_optimize(char* input_file, char* output_file, int exif_flag, char* exif_src) {
|
||||
int cclt_jpeg_optimize(char* input_file, char* output_file, int exif_flag, char* exif_src)
|
||||
{
|
||||
//TODO Bug on normal compress: the input file is a bogus long string
|
||||
// Happened with a (bugged) server connection
|
||||
//File pointer for both input and output
|
||||
|
@ -68,7 +70,6 @@ int cclt_jpeg_optimize(char* input_file, char* output_file, int exif_flag, char*
|
|||
dstinfo.err = jpeg_std_error(&jdsterr);
|
||||
jpeg_create_compress(&dstinfo);
|
||||
|
||||
|
||||
//Open the input file
|
||||
fp = fopen(input_file, "r");
|
||||
|
||||
|
@ -89,8 +90,7 @@ int cclt_jpeg_optimize(char* input_file, char* output_file, int exif_flag, char*
|
|||
}
|
||||
|
||||
//Read the input headers
|
||||
(void) jpeg_read_header(&srcinfo, TRUE);
|
||||
|
||||
(void)jpeg_read_header(&srcinfo, TRUE);
|
||||
|
||||
//Read input coefficents
|
||||
src_coef_arrays = jpeg_read_coefficients(&srcinfo);
|
||||
|
@ -139,7 +139,7 @@ int cclt_jpeg_optimize(char* input_file, char* output_file, int exif_flag, char*
|
|||
//Finish and free
|
||||
jpeg_finish_compress(&dstinfo);
|
||||
jpeg_destroy_compress(&dstinfo);
|
||||
(void) jpeg_finish_decompress(&srcinfo);
|
||||
(void)jpeg_finish_decompress(&srcinfo);
|
||||
jpeg_destroy_decompress(&srcinfo);
|
||||
|
||||
//Close the output file
|
||||
|
@ -148,7 +148,8 @@ int cclt_jpeg_optimize(char* input_file, char* output_file, int exif_flag, char*
|
|||
return 0;
|
||||
}
|
||||
|
||||
void cclt_jpeg_compress(char* output_file, unsigned char* image_buffer, cclt_jpeg_parameters* pars) {
|
||||
void cclt_jpeg_compress(char* output_file, unsigned char* image_buffer, cclt_jpeg_parameters* pars)
|
||||
{
|
||||
FILE* fp;
|
||||
tjhandle tjCompressHandle;
|
||||
unsigned char* output_buffer;
|
||||
|
@ -159,38 +160,38 @@ void cclt_jpeg_compress(char* output_file, unsigned char* image_buffer, cclt_jpe
|
|||
//Check for errors
|
||||
//TODO Use UNIX error messages
|
||||
if (fp == NULL) {
|
||||
trigger_error(106, true, output_file);
|
||||
}
|
||||
trigger_error(106, true, output_file);
|
||||
}
|
||||
|
||||
output_buffer = NULL;
|
||||
tjCompressHandle = tjInitCompress();
|
||||
output_buffer = NULL;
|
||||
tjCompressHandle = tjInitCompress();
|
||||
|
||||
//TODO Error checks
|
||||
tjCompress2(tjCompressHandle,
|
||||
image_buffer,
|
||||
pars->width,
|
||||
0,
|
||||
pars->height,
|
||||
pars->color_space,
|
||||
&output_buffer,
|
||||
&output_size,
|
||||
pars->subsample,
|
||||
pars->quality,
|
||||
pars->dct_method);
|
||||
//TODO Error checks
|
||||
tjCompress2(tjCompressHandle,
|
||||
image_buffer,
|
||||
pars->width,
|
||||
0,
|
||||
pars->height,
|
||||
pars->color_space,
|
||||
&output_buffer,
|
||||
&output_size,
|
||||
pars->subsample,
|
||||
pars->quality,
|
||||
pars->dct_method);
|
||||
|
||||
fwrite(output_buffer, output_size, 1, fp);
|
||||
|
||||
fclose(fp);
|
||||
tjDestroy(tjCompressHandle);
|
||||
tjFree(output_buffer);
|
||||
fwrite(output_buffer, output_size, 1, fp);
|
||||
|
||||
fclose(fp);
|
||||
tjDestroy(tjCompressHandle);
|
||||
tjFree(output_buffer);
|
||||
}
|
||||
|
||||
unsigned char* cclt_jpeg_decompress(char* fileName, cclt_jpeg_parameters* pars) {
|
||||
unsigned char* cclt_jpeg_decompress(char* fileName, cclt_jpeg_parameters* pars)
|
||||
{
|
||||
|
||||
//TODO I/O Error handling
|
||||
|
||||
FILE *file = NULL;
|
||||
FILE* file = NULL;
|
||||
int res = 0;
|
||||
long int sourceJpegBufferSize = 0;
|
||||
unsigned char* sourceJpegBuffer = NULL;
|
||||
|
@ -233,7 +234,8 @@ unsigned char* cclt_jpeg_decompress(char* fileName, cclt_jpeg_parameters* pars)
|
|||
return temp;
|
||||
}
|
||||
|
||||
void jcopy_markers_execute (j_decompress_ptr srcinfo, j_compress_ptr dstinfo) {
|
||||
void jcopy_markers_execute(j_decompress_ptr srcinfo, j_compress_ptr dstinfo)
|
||||
{
|
||||
jpeg_saved_marker_ptr marker;
|
||||
|
||||
/* In the current implementation, we don't actually need to examine the
|
||||
|
@ -242,25 +244,11 @@ void jcopy_markers_execute (j_decompress_ptr srcinfo, j_compress_ptr dstinfo) {
|
|||
* if the encoder library already wrote one.
|
||||
*/
|
||||
for (marker = srcinfo->marker_list; marker != NULL; marker = marker->next) {
|
||||
if (dstinfo->write_JFIF_header &&
|
||||
marker->marker == JPEG_APP0 &&
|
||||
marker->data_length >= 5 &&
|
||||
GETJOCTET(marker->data[0]) == 0x4A &&
|
||||
GETJOCTET(marker->data[1]) == 0x46 &&
|
||||
GETJOCTET(marker->data[2]) == 0x49 &&
|
||||
GETJOCTET(marker->data[3]) == 0x46 &&
|
||||
GETJOCTET(marker->data[4]) == 0)
|
||||
continue; /* reject duplicate JFIF */
|
||||
if (dstinfo->write_Adobe_marker &&
|
||||
marker->marker == JPEG_APP0+14 &&
|
||||
marker->data_length >= 5 &&
|
||||
GETJOCTET(marker->data[0]) == 0x41 &&
|
||||
GETJOCTET(marker->data[1]) == 0x64 &&
|
||||
GETJOCTET(marker->data[2]) == 0x6F &&
|
||||
GETJOCTET(marker->data[3]) == 0x62 &&
|
||||
GETJOCTET(marker->data[4]) == 0x65)
|
||||
continue; /* reject duplicate Adobe */
|
||||
if (dstinfo->write_JFIF_header && marker->marker == JPEG_APP0 && marker->data_length >= 5 && GETJOCTET(marker->data[0]) == 0x4A && GETJOCTET(marker->data[1]) == 0x46 && GETJOCTET(marker->data[2]) == 0x49 && GETJOCTET(marker->data[3]) == 0x46 && GETJOCTET(marker->data[4]) == 0)
|
||||
continue; /* reject duplicate JFIF */
|
||||
if (dstinfo->write_Adobe_marker && marker->marker == JPEG_APP0 + 14 && marker->data_length >= 5 && GETJOCTET(marker->data[0]) == 0x41 && GETJOCTET(marker->data[1]) == 0x64 && GETJOCTET(marker->data[2]) == 0x6F && GETJOCTET(marker->data[3]) == 0x62 && GETJOCTET(marker->data[4]) == 0x65)
|
||||
continue; /* reject duplicate Adobe */
|
||||
jpeg_write_marker(dstinfo, marker->marker,
|
||||
marker->data, marker->data_length);
|
||||
marker->data, marker->data_length);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ int cclt_jpeg_optimize(char* input_file, char* output_file, int exif_flag, char*
|
|||
struct jpeg_decompress_struct cclt_get_markers(char* input);
|
||||
void cclt_jpeg_compress(char* output_file, unsigned char* image_buffer, cclt_jpeg_parameters* pars);
|
||||
unsigned char* cclt_jpeg_decompress(char* fileName, cclt_jpeg_parameters* pars);
|
||||
void jcopy_markers_execute (j_decompress_ptr srcinfo, j_compress_ptr dstinfo);
|
||||
|
||||
void jcopy_markers_execute(j_decompress_ptr srcinfo, j_compress_ptr dstinfo);
|
||||
|
||||
#endif
|
||||
|
|
14
src/main.c
14
src/main.c
|
@ -28,7 +28,8 @@
|
|||
// we're gonna go in a infinite loop
|
||||
// TODO Trigger a warning if you are overwriting files
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
errno = 0;
|
||||
off_t i_t_size = 0, o_t_size = 0;
|
||||
// Parse arguments
|
||||
|
@ -42,12 +43,13 @@ int main(int argc, char *argv[]) {
|
|||
diff = clock() - start;
|
||||
long msec = diff * 1000 / CLOCKS_PER_SEC;
|
||||
|
||||
fprintf(stdout, "-------------------------------\nCompression completed in "
|
||||
fprintf(stdout, "-------------------------------\n"
|
||||
"Compression completed in "
|
||||
"%lum%lus%lums\n%s -> %s [%.2f%% | %s]\n",
|
||||
msec / 1000 / 60, msec / 1000 % 60, msec % 1000,
|
||||
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)));
|
||||
msec / 1000 / 60, msec / 1000 % 60, msec % 1000,
|
||||
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)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
14
src/png.c
14
src/png.c
|
@ -7,7 +7,8 @@
|
|||
#include "png.h"
|
||||
#include "error.h"
|
||||
|
||||
void cclt_png_optimize(char* input, char* output, cclt_png_parameters* pars) {
|
||||
void cclt_png_optimize(char* input, char* output, cclt_png_parameters* pars)
|
||||
{
|
||||
//TODO Error handling
|
||||
CZopfliPNGOptions png_options;
|
||||
|
||||
|
@ -33,11 +34,12 @@ void cclt_png_optimize(char* input, char* output, cclt_png_parameters* pars) {
|
|||
}
|
||||
|
||||
if (CZopfliPNGOptimize(orig_buffer,
|
||||
orig_buffer_size,
|
||||
&png_options,
|
||||
0,
|
||||
&resultpng,
|
||||
&resultpng_size) != 0) {
|
||||
orig_buffer_size,
|
||||
&png_options,
|
||||
0,
|
||||
&resultpng,
|
||||
&resultpng_size)
|
||||
!= 0) {
|
||||
trigger_error(17, true);
|
||||
}
|
||||
|
||||
|
|
106
src/utils.c
106
src/utils.c
|
@ -14,68 +14,69 @@
|
|||
#include <math.h>
|
||||
|
||||
#ifdef __linux
|
||||
#include <linux/limits.h>
|
||||
#include <linux/limits.h>
|
||||
#elif __APPLE__
|
||||
#include <sys/syslimits.h>
|
||||
#include <sys/syslimits.h>
|
||||
#endif
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
int string_to_int(char* in_string) {
|
||||
int string_to_int(char* in_string)
|
||||
{
|
||||
long value = 0;
|
||||
char* endptr;
|
||||
errno = 0; //Error checking
|
||||
|
||||
value = strtol(in_string, &endptr, 0); //Convert the string
|
||||
|
||||
//Check errors
|
||||
if ((errno == ERANGE) || (errno != 0 && value == 0)) {
|
||||
fprintf(stderr, "[ERROR] Cannot parse quality value.\n");
|
||||
exit(-8);
|
||||
}
|
||||
trigger_error(8, true);
|
||||
}
|
||||
|
||||
if (endptr == in_string) {
|
||||
fprintf(stderr, "[ERROR] Parse error. No digits were found for -q option.\n");
|
||||
exit(-7);
|
||||
}
|
||||
if (endptr == in_string) {
|
||||
trigger_error(7, true);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void print_help() {
|
||||
void print_help()
|
||||
{
|
||||
fprintf(stdout,
|
||||
"CaesiumCLT - Caesium Command Line Tools\n\n"
|
||||
"Usage: caesiumclt [OPTIONS] INPUT...\n"
|
||||
"Compress your pictures up to 90%% without visible quality loss.\n\n"
|
||||
|
||||
"Options:\n"
|
||||
"\t-q\tset output file quality between [1-100], JPEG only\n"
|
||||
"\t-e\tkeeps EXIF info during compression\n"
|
||||
"\t-o\toutput folder\n"
|
||||
"\t-l\tuse lossless optimization\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-h\tdisplay this help and exit\n"
|
||||
"\t-v\toutput version information and exit\n\n");
|
||||
"\t-q\tset output file quality between [1-100], JPEG only\n"
|
||||
"\t-e\tkeeps EXIF info during compression\n"
|
||||
"\t-o\toutput folder\n"
|
||||
"\t-l\tuse lossless optimization\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-h\tdisplay this help and exit\n"
|
||||
"\t-v\toutput version information and exit\n\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
//TODO Recheck
|
||||
int mkpath(const char *pathname, mode_t mode) {
|
||||
int mkpath(const char* pathname, mode_t mode)
|
||||
{
|
||||
|
||||
char parent[PATH_MAX], *p;
|
||||
/* make a parent directory path */
|
||||
strncpy(parent, pathname, sizeof(parent));
|
||||
parent[sizeof(parent) - 1] = '\0';
|
||||
for (p = parent + strlen(parent); *p != '/' && p != parent; p--);
|
||||
for (p = parent + strlen(parent); *p != '/' && p != parent; p--)
|
||||
;
|
||||
*p = '\0';
|
||||
/* try make parent directory */
|
||||
if(p != parent && mkpath(parent, mode) != 0) {
|
||||
if (p != parent && mkpath(parent, mode) != 0) {
|
||||
return -1;
|
||||
}
|
||||
/* make this one if parent has been made */
|
||||
if(mkdir(pathname, mode) == 0) {
|
||||
if (mkdir(pathname, mode) == 0) {
|
||||
return 0;
|
||||
}
|
||||
/* if it already exists that is fine */
|
||||
|
@ -85,10 +86,11 @@ int mkpath(const char *pathname, mode_t mode) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
void scan_folder(cclt_parameters* parameters, char* basedir, int recur) {
|
||||
//TODO CRITIAL Pass list as 1st parameter
|
||||
DIR *dir;
|
||||
struct dirent *ent;
|
||||
void scan_folder(cclt_parameters* parameters, char* basedir, int recur)
|
||||
{
|
||||
//TODO CRITICAL Pass list as 1st parameter
|
||||
DIR* dir;
|
||||
struct dirent* ent;
|
||||
char* entpath = NULL;
|
||||
struct stat s;
|
||||
|
||||
|
@ -126,68 +128,68 @@ void scan_folder(cclt_parameters* parameters, char* basedir, int recur) {
|
|||
parameters->input_files_count++;
|
||||
//Alloc new room for the array
|
||||
parameters->input_files = realloc(parameters->input_files, (n + 1) * sizeof(char*));
|
||||
parameters->input_files[n] = (char*) malloc(strlen(entpath) * sizeof(char));
|
||||
parameters->input_files[n] = (char*)malloc(strlen(entpath) * sizeof(char));
|
||||
//Copy the file path in the array
|
||||
parameters->input_files[n] = strcpy(parameters->input_files[n], entpath);
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
} else {
|
||||
fprintf(stderr, "[ERROR] Failed to open folder.\n");
|
||||
exit(-19);
|
||||
trigger_error(19, true, ptr);
|
||||
}
|
||||
free(entpath);
|
||||
}
|
||||
|
||||
enum image_type detect_image_type(char* path) {
|
||||
enum image_type detect_image_type(char* path)
|
||||
{
|
||||
//Open the file
|
||||
FILE* fp;
|
||||
unsigned char* type_buffer = (unsigned char*) malloc(2);
|
||||
enum image_type type = UNKN;
|
||||
|
||||
unsigned char* type_buffer = (unsigned char*)malloc(2);
|
||||
|
||||
fp = fopen(path, "r");
|
||||
|
||||
if (fp == NULL) {
|
||||
fprintf(stderr, "[ERROR] Cannot open input file for type detection.\n");
|
||||
exit(-14);
|
||||
trigger_error(14, true, path);
|
||||
}
|
||||
//Read enough bytes
|
||||
if (fread(type_buffer, 1, 2, fp) < 2) {
|
||||
fprintf(stderr, "[ERROR] Cannot read file type.\n");
|
||||
exit(-15);
|
||||
trigger_error(15, true, path);
|
||||
}
|
||||
//We don't need it anymore
|
||||
fclose(fp);
|
||||
|
||||
//Check the bytes against the JPEG and PNG specs
|
||||
if (((int) type_buffer[0] == 0xFF) && ((int) type_buffer[1] == 0xD8)) {
|
||||
free(type_buffer);
|
||||
return JPEG;
|
||||
} else if (((int) type_buffer[0] == 0x89) && ((int) type_buffer[1] == 0x50)) {
|
||||
free(type_buffer);
|
||||
return PNG;
|
||||
} else {
|
||||
free(type_buffer);
|
||||
return UNKN;
|
||||
if (((int)type_buffer[0] == 0xFF) && ((int)type_buffer[1] == 0xD8)) {
|
||||
type = JPEG;
|
||||
} else if (((int)type_buffer[0] == 0x89) && ((int)type_buffer[1] == 0x50)) {
|
||||
type = PNG;
|
||||
}
|
||||
|
||||
free(type_buffer);
|
||||
return type;
|
||||
}
|
||||
|
||||
int is_directory(const char *file_path) {
|
||||
int is_directory(const char* file_path)
|
||||
{
|
||||
struct stat s;
|
||||
stat(file_path, &s);
|
||||
return S_ISDIR(s.st_mode);
|
||||
}
|
||||
|
||||
char* get_human_size(long size) {
|
||||
char* get_human_size(long size)
|
||||
{
|
||||
//We should not get more than TB images
|
||||
char* unit[5] = {"B", "KB", "MB", "GB", "TB"};
|
||||
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));
|
||||
char* final = (char*)malloc(((int)(floor(log10(labs(size))) + 4)) * sizeof(char));
|
||||
|
||||
//If the order exceeds 4, something is fishy
|
||||
if (order > 4) {
|
||||
fprintf(stdout, "[WARNING] Do you really have such a huge file?\n");
|
||||
trigger_error(21, false);
|
||||
order = 4;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,13 +8,13 @@
|
|||
#include "ccltypes.h"
|
||||
|
||||
#define APP_VERSION "0.9.1"
|
||||
#define BUILD 20160808
|
||||
#define BUILD 20160922
|
||||
|
||||
int string_to_int(char* in_string);
|
||||
void print_help();
|
||||
int mkpath(const char *pathname, mode_t mode);
|
||||
int mkpath(const char* pathname, mode_t mode);
|
||||
enum image_type detect_image_type(char* path);
|
||||
int is_directory(const char *file_path);
|
||||
int is_directory(const char* file_path);
|
||||
void scan_folder(cclt_parameters* parameters, char* basedir, int recur);
|
||||
char* get_human_size(long size);
|
||||
|
||||
|
|
Loading…
Reference in New Issue