commit
ffb26fb80b
|
@ -1,4 +1,4 @@
|
|||
bin_PROGRAMS = caesiumclt
|
||||
caesiumclt_SOURCES = main.c jpeg.c compresshelper.c utils.c png.c lodepng.c
|
||||
caesiumclt_CFLAGS = -Wall -D_FILE_OFFSET_BITS=64 -std=c99
|
||||
caesiumclt_LDADD = -lm
|
||||
caesiumclt_LDADD = -lm
|
||||
|
|
|
@ -12,20 +12,33 @@
|
|||
#include "jpeg.h"
|
||||
#include "png.h"
|
||||
|
||||
//TODO CRITICAL It does not recognize single files as input. Why.
|
||||
void initialize_jpeg_parameters(cclt_parameters* par) {
|
||||
|
||||
par->jpeg.quality = 0;
|
||||
par->jpeg.width = 0;
|
||||
par->jpeg.height = 0;
|
||||
par->jpeg.color_space = TJCS_RGB;
|
||||
par->jpeg.dct_method = TJFLAG_FASTDCT;
|
||||
par->jpeg.exif_copy = 0;
|
||||
par->jpeg.lossless = 0;
|
||||
}
|
||||
|
||||
cclt_compress_parameters initialize_compression_parameters() {
|
||||
cclt_compress_parameters par;
|
||||
void initialize_png_parameters(cclt_parameters* par) {
|
||||
par->png.iterations = 15;
|
||||
par->png.iterations_large = 5;
|
||||
par->png.block_split_strategy = 4;
|
||||
par->png.lossy_8 = 1;
|
||||
par->png.transparent = 1;
|
||||
par->png.auto_filter_strategy = 1;
|
||||
}
|
||||
|
||||
cclt_parameters initialize_compression_parameters() {
|
||||
cclt_parameters par;
|
||||
|
||||
initialize_jpeg_parameters(&par);
|
||||
initialize_png_parameters(&par);
|
||||
|
||||
par.quality = 0;
|
||||
par.width = 0;
|
||||
par.height = 0;
|
||||
par.color_space = TJCS_RGB;
|
||||
par.dct_method = TJFLAG_FASTDCT;
|
||||
par.output_folder = NULL;
|
||||
par.exif_copy = 0;
|
||||
par.lossless = 0;
|
||||
par.input_files_count = 0;
|
||||
par.recursive = 0;
|
||||
par.input_files = NULL;
|
||||
|
@ -34,21 +47,20 @@ cclt_compress_parameters initialize_compression_parameters() {
|
|||
return par;
|
||||
}
|
||||
|
||||
cclt_compress_parameters parse_arguments(int argc, char* argv[]) {
|
||||
cclt_parameters parse_arguments(int argc, char* argv[]) {
|
||||
|
||||
//Initialize default params
|
||||
cclt_compress_parameters parameters = initialize_compression_parameters();
|
||||
cclt_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("CCLT - Caesium Command Line Tools - Version %s (Build: %d)\n", APP_VERSION, BUILD);
|
||||
printf("CaesiumCLT - Caesium Command Line Tools - Version %s (Build: %d)\n", APP_VERSION, BUILD);
|
||||
exit(0);
|
||||
break;
|
||||
case '?':
|
||||
//TODO if -o not specified or empty, use current. Useful?
|
||||
if (optopt == 'q' || optopt == 'o' || optopt == 's') {
|
||||
fprintf (stderr, "Option -%c requires an argument.\n", optopt);
|
||||
//Arguments without values
|
||||
|
@ -65,13 +77,13 @@ cclt_compress_parameters parse_arguments(int argc, char* argv[]) {
|
|||
fprintf(stderr, "Parameter expected.\n");
|
||||
break;
|
||||
case 'q':
|
||||
parameters.quality = string_to_int(optarg);
|
||||
parameters.jpeg.quality = string_to_int(optarg);
|
||||
break;
|
||||
case 'e':
|
||||
parameters.exif_copy = 1;
|
||||
parameters.jpeg.exif_copy = 1;
|
||||
break;
|
||||
case 'l':
|
||||
parameters.lossless = 1;
|
||||
parameters.jpeg.lossless = 1;
|
||||
break;
|
||||
case 'o':
|
||||
parameters.output_folder = optarg;
|
||||
|
@ -116,19 +128,19 @@ cclt_compress_parameters parse_arguments(int argc, char* argv[]) {
|
|||
return parameters;
|
||||
}
|
||||
|
||||
int cclt_compress_routine(char* input, char* output, cclt_compress_parameters* pars) {
|
||||
int cclt_compress_routine(char* input, char* output, cclt_parameters* pars) {
|
||||
enum image_type type = detect_image_type(input);
|
||||
if (type == JPEG && pars->lossless == 0) {
|
||||
cclt_jpeg_compress(output, cclt_jpeg_decompress(input, pars), pars);
|
||||
cclt_jpeg_optimize(output, output, pars->exif_copy, input);
|
||||
} else if (type == JPEG && pars->lossless != 0) {
|
||||
cclt_jpeg_optimize(input, output, pars->exif_copy, 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->quality != 0) {
|
||||
if (pars->jpeg.quality != 0) {
|
||||
printf("PNG file, ignoring quality parameter.\n");
|
||||
}
|
||||
cclt_png_optimize(input, output);
|
||||
cclt_png_optimize(input, output, &pars->png);
|
||||
} else {
|
||||
printf("Unknown file type.\n");
|
||||
return -1;
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
#include "utils.h"
|
||||
|
||||
cclt_compress_parameters initialize_compression_parameters();
|
||||
cclt_compress_parameters parse_arguments(int argc, char* argv[]);
|
||||
int cclt_compress_routine(char* input, char* output, cclt_compress_parameters* pars); //Returns -1 if the file type is unknown
|
||||
cclt_parameters initialize_compression_parameters();
|
||||
cclt_parameters parse_arguments(int argc, char* argv[]);
|
||||
int cclt_compress_routine(char* input, char* output, cclt_parameters* pars); //Returns -1 if the file type is unknown
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
115
src/jpeg.c
115
src/jpeg.c
|
@ -30,10 +30,10 @@ struct jpeg_decompress_struct cclt_get_markers(char* input) {
|
|||
exit(-13);
|
||||
}
|
||||
|
||||
//Create the IO instance for the input file
|
||||
//Create the IO instance for the input file
|
||||
jpeg_stdio_src(&einfo, fp);
|
||||
|
||||
//Save EXIF info
|
||||
//Save EXIF info
|
||||
for (int m = 0; m < 16; m++) {
|
||||
jpeg_save_markers(&einfo, JPEG_APP0 + m, 0xFFFF);
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ int cclt_jpeg_optimize(char* input_file, char* output_file, int exif_flag, char*
|
|||
struct jpeg_decompress_struct srcinfo;
|
||||
struct jpeg_compress_struct dstinfo;
|
||||
|
||||
//Error handling
|
||||
//Error handling
|
||||
struct jpeg_error_mgr jsrcerr, jdsterr;
|
||||
|
||||
//Input/Output array coefficents
|
||||
|
@ -69,7 +69,7 @@ int cclt_jpeg_optimize(char* input_file, char* output_file, int exif_flag, char*
|
|||
jpeg_create_compress(&dstinfo);
|
||||
|
||||
|
||||
//Open the input file
|
||||
//Open the input file
|
||||
fp = fopen(input_file, "r");
|
||||
|
||||
//Check for errors
|
||||
|
@ -82,19 +82,20 @@ int cclt_jpeg_optimize(char* input_file, char* output_file, int exif_flag, char*
|
|||
//Create the IO istance for the input file
|
||||
jpeg_stdio_src(&srcinfo, fp);
|
||||
|
||||
//Save EXIF info
|
||||
//Save EXIF info
|
||||
if (exif_flag == 1) {
|
||||
for (int m = 0; m < 16; m++) {
|
||||
jpeg_save_markers(&srcinfo, JPEG_APP0 + m, 0xFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
//Read the input headers
|
||||
//Read the input headers
|
||||
(void) jpeg_read_header(&srcinfo, TRUE);
|
||||
|
||||
|
||||
//Read input coefficents
|
||||
src_coef_arrays = jpeg_read_coefficients(&srcinfo);
|
||||
//jcopy_markers_setup(&srcinfo, copyoption);
|
||||
//jcopy_markers_setup(&srcinfo, copyoption);
|
||||
|
||||
//Copy parameters
|
||||
jpeg_copy_critical_parameters(&srcinfo, &dstinfo);
|
||||
|
@ -116,7 +117,7 @@ int cclt_jpeg_optimize(char* input_file, char* output_file, int exif_flag, char*
|
|||
|
||||
//CRITICAL - This is the optimization step
|
||||
dstinfo.optimize_coding = TRUE;
|
||||
//Progressive
|
||||
//Progressive
|
||||
jpeg_simple_progression(&dstinfo);
|
||||
|
||||
//Set the output file parameters
|
||||
|
@ -125,19 +126,19 @@ int cclt_jpeg_optimize(char* input_file, char* output_file, int exif_flag, char*
|
|||
//Actually write the coefficents
|
||||
jpeg_write_coefficients(&dstinfo, dst_coef_arrays);
|
||||
|
||||
//Write EXIF
|
||||
//Write EXIF
|
||||
if (exif_flag == 1) {
|
||||
if (strcmp(input_file, exif_src) == 0) {
|
||||
jcopy_markers_execute(&srcinfo, &dstinfo);
|
||||
} else {
|
||||
//For standard compression EXIF data
|
||||
//For standard compression EXIF data
|
||||
struct jpeg_decompress_struct einfo = cclt_get_markers(exif_src);
|
||||
jcopy_markers_execute(&einfo, &dstinfo);
|
||||
jpeg_destroy_decompress(&einfo);
|
||||
}
|
||||
}
|
||||
|
||||
//Finish and free
|
||||
//Finish and free
|
||||
jpeg_finish_compress(&dstinfo);
|
||||
jpeg_destroy_compress(&dstinfo);
|
||||
(void) jpeg_finish_decompress(&srcinfo);
|
||||
|
@ -149,7 +150,7 @@ 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_compress_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;
|
||||
|
@ -160,8 +161,8 @@ void cclt_jpeg_compress(char* output_file, unsigned char* image_buffer, cclt_com
|
|||
//Check for errors
|
||||
//TODO Use UNIX error messages
|
||||
if (fp == NULL) {
|
||||
printf("OUTPUT: Failed to open output \"%s\"\n", output_file);
|
||||
return;
|
||||
printf("OUTPUT: Failed to open output \"%s\"\n", output_file);
|
||||
return;
|
||||
}
|
||||
|
||||
output_buffer = NULL;
|
||||
|
@ -169,16 +170,16 @@ void cclt_jpeg_compress(char* output_file, unsigned char* image_buffer, cclt_com
|
|||
|
||||
//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);
|
||||
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);
|
||||
|
||||
|
@ -188,49 +189,49 @@ void cclt_jpeg_compress(char* output_file, unsigned char* image_buffer, cclt_com
|
|||
|
||||
}
|
||||
|
||||
unsigned char* cclt_jpeg_decompress(char* fileName, cclt_compress_parameters* pars) {
|
||||
unsigned char* cclt_jpeg_decompress(char* fileName, cclt_jpeg_parameters* pars) {
|
||||
|
||||
//TODO I/O Error handling
|
||||
|
||||
FILE *file = NULL;
|
||||
int res = 0;
|
||||
long int sourceJpegBufferSize = 0;
|
||||
unsigned char* sourceJpegBuffer = NULL;
|
||||
tjhandle tjDecompressHandle;
|
||||
int fileWidth = 0, fileHeight = 0, jpegSubsamp = 0, colorSpace = 0;
|
||||
FILE *file = NULL;
|
||||
int res = 0;
|
||||
long int sourceJpegBufferSize = 0;
|
||||
unsigned char* sourceJpegBuffer = NULL;
|
||||
tjhandle tjDecompressHandle;
|
||||
int fileWidth = 0, fileHeight = 0, jpegSubsamp = 0, colorSpace = 0;
|
||||
|
||||
//TODO No error checks here
|
||||
file = fopen(fileName, "rb");
|
||||
res = fseek(file, 0, SEEK_END);
|
||||
sourceJpegBufferSize = ftell(file);
|
||||
sourceJpegBuffer = tjAlloc(sourceJpegBufferSize);
|
||||
//TODO No error checks here
|
||||
file = fopen(fileName, "rb");
|
||||
res = fseek(file, 0, SEEK_END);
|
||||
sourceJpegBufferSize = ftell(file);
|
||||
sourceJpegBuffer = tjAlloc(sourceJpegBufferSize);
|
||||
|
||||
res = fseek(file, 0, SEEK_SET);
|
||||
res = fread(sourceJpegBuffer, (long)sourceJpegBufferSize, 1, file);
|
||||
tjDecompressHandle = tjInitDecompress();
|
||||
res = tjDecompressHeader3(tjDecompressHandle, sourceJpegBuffer, sourceJpegBufferSize, &fileWidth, &fileHeight, &jpegSubsamp, &colorSpace);
|
||||
res = fseek(file, 0, SEEK_SET);
|
||||
res = fread(sourceJpegBuffer, (long)sourceJpegBufferSize, 1, file);
|
||||
tjDecompressHandle = tjInitDecompress();
|
||||
res = tjDecompressHeader3(tjDecompressHandle, sourceJpegBuffer, sourceJpegBufferSize, &fileWidth, &fileHeight, &jpegSubsamp, &colorSpace);
|
||||
|
||||
pars->width = fileWidth;
|
||||
pars->height = fileHeight;
|
||||
pars->width = fileWidth;
|
||||
pars->height = fileHeight;
|
||||
|
||||
pars->subsample = jpegSubsamp;
|
||||
pars->color_space = colorSpace;
|
||||
pars->subsample = jpegSubsamp;
|
||||
pars->color_space = colorSpace;
|
||||
|
||||
unsigned char* temp = tjAlloc(pars->width * pars->height * tjPixelSize[pars->color_space]);
|
||||
unsigned char* temp = tjAlloc(pars->width * pars->height * tjPixelSize[pars->color_space]);
|
||||
|
||||
res = tjDecompress2(tjDecompressHandle,
|
||||
sourceJpegBuffer,
|
||||
sourceJpegBufferSize,
|
||||
temp,
|
||||
pars->width,
|
||||
0,
|
||||
pars->height,
|
||||
pars->color_space,
|
||||
pars->dct_method);
|
||||
res = tjDecompress2(tjDecompressHandle,
|
||||
sourceJpegBuffer,
|
||||
sourceJpegBufferSize,
|
||||
temp,
|
||||
pars->width,
|
||||
0,
|
||||
pars->height,
|
||||
pars->color_space,
|
||||
pars->dct_method);
|
||||
|
||||
//fwrite(temp, pars->width * pars->height * tjPixelSize[pars->color_space], 1, fopen("/Users/lymphatus/Desktop/tmp/compresse/ccc", "w"));
|
||||
//fwrite(temp, pars->width * pars->height * tjPixelSize[pars->color_space], 1, fopen("/Users/lymphatus/Desktop/tmp/compresse/ccc", "w"));
|
||||
|
||||
tjDestroy(tjDecompressHandle);
|
||||
tjDestroy(tjDecompressHandle);
|
||||
|
||||
return temp;
|
||||
return temp;
|
||||
}
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
|
||||
int cclt_jpeg_optimize(char* input_file, char* output_file, int exif_flag, char* exif_src);
|
||||
struct jpeg_decompress_struct cclt_get_markers(char* input);
|
||||
void cclt_jpeg_compress(char* output_file, unsigned char* image_buffer, cclt_compress_parameters* pars);
|
||||
unsigned char* cclt_jpeg_decompress(char* fileName, cclt_compress_parameters* pars);
|
||||
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);
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
27
src/main.c
27
src/main.c
|
@ -28,7 +28,7 @@
|
|||
|
||||
//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_compress_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;
|
||||
|
@ -111,15 +111,15 @@ int main (int argc, char *argv[]) {
|
|||
off_t i_t_size = 0, o_t_size = 0;
|
||||
|
||||
//Parse arguments
|
||||
cclt_compress_parameters pars = parse_arguments(argc, argv);
|
||||
cclt_parameters pars = parse_arguments(argc, argv);
|
||||
|
||||
//Either -l or -q must be set but not together
|
||||
if (!((pars.lossless == 1) ^ (pars.quality > 0))) {
|
||||
if (!((pars.jpeg.lossless == 1) ^ (pars.jpeg.quality > 0))) {
|
||||
//Both or none are set
|
||||
if (pars.lossless == 1 && pars.quality > 0) {
|
||||
if (pars.jpeg.lossless == 1 && pars.jpeg.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) {
|
||||
} else if (pars.jpeg.lossless == 0 && pars.jpeg.quality <= 0) {
|
||||
fprintf(stderr, "Either -l or -q must be set. Aborting.\n");
|
||||
print_help();
|
||||
exit(-2);
|
||||
|
@ -127,7 +127,7 @@ int main (int argc, char *argv[]) {
|
|||
} 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) {
|
||||
if (!(pars.jpeg.quality >= 1 && pars.jpeg.quality <= 100) && pars.jpeg.lossless == 0) {
|
||||
fprintf(stderr, "Quality must be within a [1-100] range. Aborting.\n");
|
||||
exit(-3);
|
||||
}
|
||||
|
@ -155,18 +155,15 @@ int main (int argc, char *argv[]) {
|
|||
clock_t start = clock(), diff;
|
||||
//We need the file list right here
|
||||
cclt_start(&pars, &i_t_size, &o_t_size);
|
||||
/*for (int i = 0; i < pars.input_files_count; i++) {
|
||||
printf("FILE %d: %s\n", i, pars.input_files[i]);
|
||||
}*/
|
||||
diff = clock() - start;
|
||||
|
||||
fprintf(stdout, "-------------------------------\nCompression completed in %lum%lus\n%s -> %s [%.2f%% | %s]\n",
|
||||
diff / CLOCKS_PER_SEC / 60,
|
||||
diff / CLOCKS_PER_SEC % 60,
|
||||
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)));
|
||||
diff / CLOCKS_PER_SEC / 60,
|
||||
diff / CLOCKS_PER_SEC % 60,
|
||||
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;
|
||||
}
|
||||
|
|
52
src/png.c
52
src/png.c
|
@ -6,7 +6,7 @@
|
|||
#include <zopflipng/zopflipng_lib.h>
|
||||
#include "png.h"
|
||||
|
||||
void cclt_png_optimize(char* input, char* output) {
|
||||
void cclt_png_optimize(char* input, char* output, cclt_png_parameters* pars) {
|
||||
//TODO Error handling
|
||||
CZopfliPNGOptions png_options;
|
||||
|
||||
|
@ -18,35 +18,35 @@ void cclt_png_optimize(char* input, char* output) {
|
|||
unsigned char* resultpng;
|
||||
size_t resultpng_size;
|
||||
|
||||
png_options.num_iterations = 15;
|
||||
png_options.num_iterations_large = 5;
|
||||
png_options.block_split_strategy = 4;
|
||||
png_options.num_iterations = pars->iterations;
|
||||
png_options.num_iterations_large = pars->iterations_large;
|
||||
png_options.block_split_strategy = pars->block_split_strategy;
|
||||
|
||||
png_options.lossy_8bit = 1;
|
||||
png_options.lossy_transparent = 1;
|
||||
png_options.lossy_8bit = pars->lossy_8;
|
||||
png_options.lossy_transparent = pars->transparent;
|
||||
|
||||
png_options.auto_filter_strategy = 1;
|
||||
png_options.auto_filter_strategy = pars->auto_filter_strategy;
|
||||
|
||||
if (lodepng_load_file(&orig_buffer, &orig_buffer_size, input) != 0) {
|
||||
fprintf(stderr, "Error while loading PNG. Aborting.\n");
|
||||
exit(-16);
|
||||
}
|
||||
if (lodepng_load_file(&orig_buffer, &orig_buffer_size, input) != 0) {
|
||||
fprintf(stderr, "Error while loading PNG. Aborting.\n");
|
||||
exit(-16);
|
||||
}
|
||||
|
||||
if (CZopfliPNGOptimize(orig_buffer,
|
||||
orig_buffer_size,
|
||||
&png_options,
|
||||
0,
|
||||
&resultpng,
|
||||
&resultpng_size) != 0) {
|
||||
fprintf(stderr, "Error while optimizing PNG. Aborting.\n");
|
||||
exit(-17);
|
||||
}
|
||||
if (CZopfliPNGOptimize(orig_buffer,
|
||||
orig_buffer_size,
|
||||
&png_options,
|
||||
0,
|
||||
&resultpng,
|
||||
&resultpng_size) != 0) {
|
||||
fprintf(stderr, "Error while optimizing PNG. Aborting.\n");
|
||||
exit(-17);
|
||||
}
|
||||
|
||||
if (lodepng_save_file(resultpng, resultpng_size, output) != 0) {
|
||||
fprintf(stderr, "Error while writing PNG. Aborting.\n");
|
||||
exit(-18);
|
||||
}
|
||||
if (lodepng_save_file(resultpng, resultpng_size, output) != 0) {
|
||||
fprintf(stderr, "Error while writing PNG. Aborting.\n");
|
||||
exit(-18);
|
||||
}
|
||||
|
||||
free(orig_buffer);
|
||||
free(resultpng);
|
||||
free(orig_buffer);
|
||||
free(resultpng);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef CCLT_PNG
|
||||
#define CCLT_PNG
|
||||
|
||||
void cclt_png_optimize(char* input, char* output);
|
||||
#include "utils.h"
|
||||
|
||||
#endif
|
||||
void cclt_png_optimize(char* input, char* output, cclt_png_parameters* pars);
|
||||
|
||||
#endif
|
||||
|
|
14
src/utils.c
14
src/utils.c
|
@ -30,14 +30,14 @@ int string_to_int(char* in_string) {
|
|||
|
||||
//Check errors
|
||||
if ((errno == ERANGE) || (errno != 0 && value == 0)) {
|
||||
perror("strtol");
|
||||
exit(-8);
|
||||
}
|
||||
perror("strtol");
|
||||
exit(-8);
|
||||
}
|
||||
|
||||
if (endptr == in_string) {
|
||||
fprintf(stderr, "Parse error: No digits were found for -q option. Aborting.\n");
|
||||
exit(-7);
|
||||
}
|
||||
fprintf(stderr, "Parse error: No digits were found for -q option. Aborting.\n");
|
||||
exit(-7);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ int mkpath(const char *pathname, mode_t mode) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
void scan_folder(cclt_compress_parameters* parameters, char* basedir, int recur) {
|
||||
void scan_folder(cclt_parameters* parameters, char* basedir, int recur) {
|
||||
//TODO CRITIAL Pass list as 1st parameter
|
||||
DIR *dir;
|
||||
struct dirent *ent;
|
||||
|
|
27
src/utils.h
27
src/utils.h
|
@ -6,23 +6,38 @@
|
|||
#include <sys/types.h>
|
||||
|
||||
#define APP_VERSION "0.9.1-beta"
|
||||
#define BUILD 20160116
|
||||
#define BUILD 20160421
|
||||
|
||||
typedef struct cclt_compress_parameters {
|
||||
typedef struct cclt_jpeg_parameters {
|
||||
int quality;
|
||||
int width;
|
||||
int height;
|
||||
char* output_folder;
|
||||
int color_space;
|
||||
int dct_method;
|
||||
int exif_copy;
|
||||
int lossless;
|
||||
enum TJSAMP subsample;
|
||||
} cclt_jpeg_parameters;
|
||||
|
||||
typedef struct cclt_png_parameters {
|
||||
int iterations;
|
||||
int iterations_large;
|
||||
int block_split_strategy;
|
||||
int lossy_8;
|
||||
int transparent;
|
||||
int auto_filter_strategy;
|
||||
} cclt_png_parameters;
|
||||
|
||||
typedef struct cclt_parameters {
|
||||
cclt_jpeg_parameters jpeg;
|
||||
cclt_png_parameters png;
|
||||
|
||||
char* output_folder;
|
||||
char** input_files;
|
||||
int input_files_count;
|
||||
enum TJSAMP subsample;
|
||||
int recursive;
|
||||
int structure;
|
||||
} cclt_compress_parameters;
|
||||
} cclt_parameters;
|
||||
|
||||
enum image_type {
|
||||
JPEG,
|
||||
|
@ -35,7 +50,7 @@ void print_help();
|
|||
int mkpath(const char *pathname, mode_t mode);
|
||||
enum image_type detect_image_type(char* path);
|
||||
int is_directory(const char *file_path);
|
||||
void scan_folder(cclt_compress_parameters* parameters, char* basedir, int recur);
|
||||
void scan_folder(cclt_parameters* parameters, char* basedir, int recur);
|
||||
char* get_human_size(long size);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue