Decompression/Compression routine added
This commit is contained in:
parent
91ae054346
commit
8c71d0d93b
|
@ -20,7 +20,9 @@ See INSTALL for more details.
|
||||||
----------
|
----------
|
||||||
|
|
||||||
###### TODO
|
###### TODO
|
||||||
A lot of things. A more detailed list will come later on.
|
* Lossy compression
|
||||||
|
* Lossless scale
|
||||||
|
*
|
||||||
|
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
bin_PROGRAMS = caesiumclt
|
bin_PROGRAMS = caesiumclt
|
||||||
caesiumclt_SOURCES = main.c utils.c lossless.c compress.c
|
caesiumclt_SOURCES = main.c utils.c lossless.c compress.c
|
||||||
caesiumclt_CFLAGS = -Wall -D_FILE_OFFSET_BITS=64 -ljpeg -std=c99
|
caesiumclt_CFLAGS = -Wall -D_FILE_OFFSET_BITS=64 -ljpeg -lturbojpeg -std=c99
|
||||||
caesiumclt_OBJCFLAGS = -D_FILE_OFFSET_BITS=64 -ljpeg
|
caesiumclt_OBJCFLAGS = -D_FILE_OFFSET_BITS=64 -ljpeg -lturbojpeg
|
|
@ -253,8 +253,8 @@ top_build_prefix = @top_build_prefix@
|
||||||
top_builddir = @top_builddir@
|
top_builddir = @top_builddir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
caesiumclt_SOURCES = main.c utils.c lossless.c compress.c
|
caesiumclt_SOURCES = main.c utils.c lossless.c compress.c
|
||||||
caesiumclt_CFLAGS = -Wall -D_FILE_OFFSET_BITS=64 -ljpeg -std=c99
|
caesiumclt_CFLAGS = -Wall -D_FILE_OFFSET_BITS=64 -ljpeg -lturbojpeg -std=c99
|
||||||
caesiumclt_OBJCFLAGS = -D_FILE_OFFSET_BITS=64 -ljpeg
|
caesiumclt_OBJCFLAGS = -D_FILE_OFFSET_BITS=64 -ljpeg -lturbojpeg
|
||||||
all: all-am
|
all: all-am
|
||||||
|
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <jpeglib.h>
|
#include <jpeglib.h>
|
||||||
|
#include <turbojpeg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "compress.h"
|
#include "compress.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
void cclt_compress(char* output_file, unsigned char* image_buffer)
|
void cclt_compress(char* output_file, unsigned char* image_buffer, cclt_compress_parameters* pars)
|
||||||
{
|
{
|
||||||
struct jpeg_compress_struct cinfo;
|
struct jpeg_compress_struct cinfo;
|
||||||
|
|
||||||
|
@ -15,8 +17,8 @@ void cclt_compress(char* output_file, unsigned char* image_buffer)
|
||||||
int row_stride;
|
int row_stride;
|
||||||
|
|
||||||
if ((outfile = fopen(output_file, "wb")) == NULL) {
|
if ((outfile = fopen(output_file, "wb")) == NULL) {
|
||||||
fprintf(stderr, "can't open %s\n", output_file);
|
fprintf(stderr, "can't open %s\n", output_file);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
cinfo.err = jpeg_std_error(&jerr);
|
cinfo.err = jpeg_std_error(&jerr);
|
||||||
|
@ -24,35 +26,34 @@ void cclt_compress(char* output_file, unsigned char* image_buffer)
|
||||||
jpeg_create_compress(&cinfo);
|
jpeg_create_compress(&cinfo);
|
||||||
jpeg_stdio_dest(&cinfo, outfile);
|
jpeg_stdio_dest(&cinfo, outfile);
|
||||||
|
|
||||||
cinfo.image_width = 80;
|
cinfo.image_width = pars->width;
|
||||||
cinfo.image_height = 80;
|
cinfo.image_height = pars->height;
|
||||||
cinfo.input_components = 3;
|
cinfo.input_components = 3;
|
||||||
cinfo.in_color_space = JCS_RGB;
|
cinfo.in_color_space = JCS_RGB;
|
||||||
|
|
||||||
jpeg_set_defaults(&cinfo);
|
jpeg_set_defaults(&cinfo);
|
||||||
|
|
||||||
cinfo.dct_method = JDCT_FLOAT;
|
cinfo.dct_method = pars->dct_method;
|
||||||
cinfo.optimize_coding = TRUE;
|
cinfo.optimize_coding = TRUE;
|
||||||
cinfo.smoothing_factor = 50;
|
cinfo.smoothing_factor = pars->smoothing_factor;
|
||||||
jpeg_set_quality(&cinfo, 80, TRUE );
|
jpeg_set_quality(&cinfo, pars->quality, TRUE);
|
||||||
jpeg_set_colorspace(&cinfo, JCS_RGB);
|
jpeg_set_colorspace(&cinfo, JCS_RGB);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
jpeg_start_compress(&cinfo, TRUE);
|
jpeg_start_compress(&cinfo, TRUE);
|
||||||
|
|
||||||
//TODO cambia
|
row_stride = pars->width * 3;
|
||||||
row_stride = 80 * 3;//image_width * 3;
|
|
||||||
|
|
||||||
|
|
||||||
while (cinfo.next_scanline < cinfo.image_height) {
|
while (cinfo.next_scanline < cinfo.image_height) {
|
||||||
|
|
||||||
printf("%d%%\r", cinfo.next_scanline * 100 / cinfo.image_height);
|
//printf("%d%%\r", cinfo.next_scanline * 100 / cinfo.image_height);
|
||||||
|
|
||||||
row_pointer[0] = &image_buffer[cinfo.next_scanline * row_stride];
|
row_pointer[0] = &image_buffer[cinfo.next_scanline * row_stride];
|
||||||
(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
|
(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
|
||||||
}
|
}
|
||||||
printf("%d%%\n", cinfo.next_scanline * 100 / cinfo.image_height);
|
//printf("%d%%\n", cinfo.next_scanline * 100 / cinfo.image_height);
|
||||||
|
|
||||||
|
|
||||||
jpeg_finish_compress(&cinfo);
|
jpeg_finish_compress(&cinfo);
|
||||||
|
@ -62,3 +63,47 @@ void cclt_compress(char* output_file, unsigned char* image_buffer)
|
||||||
jpeg_destroy_compress(&cinfo);
|
jpeg_destroy_compress(&cinfo);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned char* cclt_decompress(char* fileName, cclt_compress_parameters* pars) {
|
||||||
|
|
||||||
|
FILE *file = NULL;
|
||||||
|
int res = 0;
|
||||||
|
long int sourceJpegBufferSize = 0;
|
||||||
|
unsigned char* sourceJpegBuffer = NULL;
|
||||||
|
tjhandle tjDecompressHandle;
|
||||||
|
int fileWidth = 0, fileHeight = 0, jpegSubsamp = 0;
|
||||||
|
|
||||||
|
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 = tjDecompressHeader2(tjDecompressHandle, sourceJpegBuffer, sourceJpegBufferSize, &fileWidth, &fileHeight, &jpegSubsamp);
|
||||||
|
|
||||||
|
int destWidth = fileWidth;
|
||||||
|
int destHeight = fileHeight;
|
||||||
|
pars->color_space = jpegSubsamp;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned char* temp = tjAlloc(destHeight * destWidth * tjPixelSize[TJPF_RGB]);
|
||||||
|
|
||||||
|
|
||||||
|
res = tjDecompress2(tjDecompressHandle,
|
||||||
|
sourceJpegBuffer,
|
||||||
|
sourceJpegBufferSize,
|
||||||
|
temp,
|
||||||
|
destWidth,
|
||||||
|
0,
|
||||||
|
destHeight,
|
||||||
|
TJPF_RGB,
|
||||||
|
TJFLAG_ACCURATEDCT);
|
||||||
|
|
||||||
|
pars->width = destWidth;
|
||||||
|
pars->height = destHeight;
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
#ifndef CCTL_COMPRESS
|
#ifndef CCLT_COMPRESS
|
||||||
#define CCTL_COMPRESS
|
#define CCLT_COMPRESS
|
||||||
|
|
||||||
void cclt_compress(char* output_file, unsigned char* image_buffer);
|
#include "utils.h"
|
||||||
|
|
||||||
|
void cclt_compress(char* output_file, unsigned char* image_buffer, cclt_compress_parameters* pars);
|
||||||
|
unsigned char* cclt_decompress(char* fileName, cclt_compress_parameters* pars);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,10 +4,11 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "lossless.h"
|
#include "lossless.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
int cclt_optimize(char* input_file, char* output_file) {
|
int cclt_optimize(char* input_file, char* output_file, int exif_flag) {
|
||||||
//File pointer for both input and output
|
//File pointer for both input and output
|
||||||
FILE* fp;
|
FILE* fp;
|
||||||
|
|
||||||
//Those will hold the input/output structs
|
//Those will hold the input/output structs
|
||||||
struct jpeg_decompress_struct srcinfo;
|
struct jpeg_decompress_struct srcinfo;
|
||||||
|
@ -17,8 +18,8 @@ int cclt_optimize(char* input_file, char* output_file) {
|
||||||
struct jpeg_error_mgr jsrcerr, jdsterr;
|
struct jpeg_error_mgr jsrcerr, jdsterr;
|
||||||
|
|
||||||
//Input/Output array coefficents
|
//Input/Output array coefficents
|
||||||
jvirt_barray_ptr * src_coef_arrays;
|
jvirt_barray_ptr* src_coef_arrays;
|
||||||
jvirt_barray_ptr * dst_coef_arrays;
|
jvirt_barray_ptr* dst_coef_arrays;
|
||||||
|
|
||||||
//Set errors and create the compress/decompress istances
|
//Set errors and create the compress/decompress istances
|
||||||
srcinfo.err = jpeg_std_error(&jsrcerr);
|
srcinfo.err = jpeg_std_error(&jsrcerr);
|
||||||
|
@ -38,12 +39,20 @@ int cclt_optimize(char* input_file, char* output_file) {
|
||||||
|
|
||||||
//Create the IO istance for the input file
|
//Create the IO istance for the input file
|
||||||
jpeg_stdio_src(&srcinfo, fp);
|
jpeg_stdio_src(&srcinfo, fp);
|
||||||
|
|
||||||
|
//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);
|
(void) jpeg_read_header(&srcinfo, TRUE);
|
||||||
|
|
||||||
//Read input coefficents
|
//Read input coefficents
|
||||||
src_coef_arrays = jpeg_read_coefficients(&srcinfo);
|
src_coef_arrays = jpeg_read_coefficients(&srcinfo);
|
||||||
|
//jcopy_markers_setup(&srcinfo, copyoption);
|
||||||
|
|
||||||
//Copy parameters
|
//Copy parameters
|
||||||
jpeg_copy_critical_parameters(&srcinfo, &dstinfo);
|
jpeg_copy_critical_parameters(&srcinfo, &dstinfo);
|
||||||
|
@ -56,7 +65,7 @@ int cclt_optimize(char* input_file, char* output_file) {
|
||||||
|
|
||||||
//Open the output one instead
|
//Open the output one instead
|
||||||
fp = fopen(output_file, "w+");
|
fp = fopen(output_file, "w+");
|
||||||
//Check for errors
|
//Check for errors
|
||||||
//TODO Use UNIX error messages
|
//TODO Use UNIX error messages
|
||||||
if (fp == NULL) {
|
if (fp == NULL) {
|
||||||
printf("OUTPUT: Failed to open file \"%s\"\n", output_file);
|
printf("OUTPUT: Failed to open file \"%s\"\n", output_file);
|
||||||
|
@ -66,13 +75,18 @@ int cclt_optimize(char* input_file, char* output_file) {
|
||||||
//CRITICAL - This is the optimization step
|
//CRITICAL - This is the optimization step
|
||||||
dstinfo.optimize_coding = TRUE;
|
dstinfo.optimize_coding = TRUE;
|
||||||
jpeg_simple_progression(&dstinfo);
|
jpeg_simple_progression(&dstinfo);
|
||||||
//dstinfo.dct_method = JDCT_ISLOW;
|
|
||||||
|
|
||||||
//Set the output file parameters
|
//Set the output file parameters
|
||||||
jpeg_stdio_dest(&dstinfo, fp);
|
jpeg_stdio_dest(&dstinfo, fp);
|
||||||
|
|
||||||
|
|
||||||
//Actually write the coefficents
|
//Actually write the coefficents
|
||||||
jpeg_write_coefficients(&dstinfo, dst_coef_arrays);
|
jpeg_write_coefficients(&dstinfo, dst_coef_arrays);
|
||||||
|
|
||||||
|
//Write EXIF
|
||||||
|
if (exif_flag == 1) {
|
||||||
|
jcopy_markers_execute(&srcinfo, &dstinfo);
|
||||||
|
}
|
||||||
|
|
||||||
//Free memory and finish
|
//Free memory and finish
|
||||||
jpeg_finish_compress(&dstinfo);
|
jpeg_finish_compress(&dstinfo);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#ifndef CCTL_LOSSLESS
|
#ifndef CCLT_LOSSLESS
|
||||||
#define CCTL_LOSSLESS
|
#define CCLT_LOSSLESS
|
||||||
|
|
||||||
int cclt_optimize(char* input_file, char* output_file);
|
int cclt_optimize(char* input_file, char* output_file, int exif_flag);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
96
src/main.c
96
src/main.c
|
@ -12,88 +12,19 @@
|
||||||
#include "compress.h"
|
#include "compress.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
#define APP_VERSION "1.9.9 BETA"
|
|
||||||
#define BUILD 20150515
|
|
||||||
|
|
||||||
/* PARAMETERS:
|
/* PARAMETERS:
|
||||||
-q quality
|
-q quality
|
||||||
-e exif
|
-e exif v
|
||||||
-o output folder
|
-o output folder v
|
||||||
-v version
|
-v version v
|
||||||
-l lossless
|
-l lossless v
|
||||||
-s scale
|
-s scale
|
||||||
-h help
|
-h help v
|
||||||
-R recursive
|
-R recursive
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//TODO Use a general fuction to support folder separators
|
//TODO Use a general fuction to support folder separators
|
||||||
|
|
||||||
cclt_compress_parameters parse_arguments(int argc, char* argv[]) {
|
|
||||||
|
|
||||||
//Initialize default params
|
|
||||||
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("CCLT - Caesium Command Line Tools - Version %s (Build: %d)\n", APP_VERSION, BUILD);
|
|
||||||
exit(0);
|
|
||||||
break;
|
|
||||||
case '?':
|
|
||||||
if (optopt == 'q' || optopt == 'o' || optopt == 's') {
|
|
||||||
fprintf (stderr, "Option -%c requires an argument.\n", optopt);
|
|
||||||
//Arguments without values
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
else if (isprint(optopt)) {
|
|
||||||
fprintf (stderr, "Unknown option `-%c'.\n", optopt);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ':':
|
|
||||||
fprintf(stderr, "Parameter expected.\n");
|
|
||||||
break;
|
|
||||||
case 'q':
|
|
||||||
parameters.quality = string_to_int(optarg);
|
|
||||||
break;
|
|
||||||
case 'e':
|
|
||||||
parameters.exif_copy = 1;
|
|
||||||
break;
|
|
||||||
case 'l':
|
|
||||||
parameters.lossless = 1;
|
|
||||||
break;
|
|
||||||
case 'o':
|
|
||||||
parameters.output_folder = optarg;
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
parameters.scaling_factor = string_to_int(optarg);
|
|
||||||
break;
|
|
||||||
case 'h':
|
|
||||||
print_help();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
int i = 0;
|
|
||||||
parameters.input_files = (char**) malloc ((argc - optind) * sizeof (char*));
|
|
||||||
while (optind < argc) {
|
|
||||||
parameters.input_files[i] = (char*) malloc (strlen(argv[optind]) * sizeof(char)); //TODO Necessary??
|
|
||||||
parameters.input_files[i] = argv[optind];
|
|
||||||
parameters.input_files_count = i + 1;
|
|
||||||
optind++;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return parameters;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main (int argc, char *argv[]) {
|
int main (int argc, char *argv[]) {
|
||||||
struct stat st_buf;
|
struct stat st_buf;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
@ -138,9 +69,8 @@ int main (int argc, char *argv[]) {
|
||||||
fprintf(stderr, "No -o option pointing to the destination folder. Aborting.\n");
|
fprintf(stderr, "No -o option pointing to the destination folder. Aborting.\n");
|
||||||
exit(-4);
|
exit(-4);
|
||||||
} else {
|
} else {
|
||||||
if (mkdir(pars.output_folder, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == -1) {
|
if (mkpath(pars.output_folder, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == -1) {
|
||||||
if (errno != EEXIST) {
|
if (errno != EEXIST) {
|
||||||
perror("mkdir");
|
|
||||||
exit(-5);
|
exit(-5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -153,7 +83,7 @@ int main (int argc, char *argv[]) {
|
||||||
for (int i = 0; i < pars.input_files_count; i++) {
|
for (int i = 0; i < pars.input_files_count; i++) {
|
||||||
off_t i_size, o_size;
|
off_t i_size, o_size;
|
||||||
int status; //Pointer for stat() call
|
int status; //Pointer for stat() call
|
||||||
char* output_filename = (char*) malloc (strlen(pars.output_folder) * sizeof(char));
|
char* output_filename = (char*) malloc ((strlen(pars.output_folder) + 2) * sizeof(char));
|
||||||
char* i_tmp = (char*) malloc (strlen(pars.input_files[i]) * sizeof(char));
|
char* i_tmp = (char*) malloc (strlen(pars.input_files[i]) * sizeof(char));
|
||||||
|
|
||||||
strcpy(i_tmp, pars.input_files[i]);
|
strcpy(i_tmp, pars.input_files[i]);
|
||||||
|
@ -163,7 +93,9 @@ int main (int argc, char *argv[]) {
|
||||||
if (output_filename[strlen(pars.output_folder - 1)] != '/') {
|
if (output_filename[strlen(pars.output_folder - 1)] != '/') {
|
||||||
strcat(output_filename, "/");
|
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));
|
output_filename = strcat(output_filename, get_filename_with_extension(i_tmp));
|
||||||
|
|
||||||
//TODO OVERALL progress update?
|
//TODO OVERALL progress update?
|
||||||
|
@ -183,7 +115,6 @@ int main (int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//Get input file size
|
//Get input file size
|
||||||
//On 32bit system, compile with -D_FILE_OFFSET_BITS=64
|
|
||||||
i_size = st_buf.st_size;
|
i_size = st_buf.st_size;
|
||||||
i_t_size += i_size;
|
i_t_size += i_size;
|
||||||
|
|
||||||
|
@ -192,9 +123,12 @@ int main (int argc, char *argv[]) {
|
||||||
|
|
||||||
//Lossless optmization requested
|
//Lossless optmization requested
|
||||||
if (pars.lossless != 0) {
|
if (pars.lossless != 0) {
|
||||||
cclt_optimize(pars.input_files[i], output_filename);
|
|
||||||
|
cclt_optimize(pars.input_files[i], output_filename, pars.exif_copy);
|
||||||
} else {
|
} else {
|
||||||
//TODO Standard compression requested
|
//TODO Standard compression requested
|
||||||
|
unsigned char* buffer = cclt_decompress(pars.input_files[i], &pars);
|
||||||
|
cclt_compress(output_filename, buffer, &pars);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Get output stats
|
//Get output stats
|
||||||
|
|
126
src/utils.c
126
src/utils.c
|
@ -6,6 +6,10 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <jpeglib.h>
|
#include <jpeglib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
@ -15,14 +19,15 @@ cclt_compress_parameters initialize_compression_parameters() {
|
||||||
par.quality = 0;
|
par.quality = 0;
|
||||||
par.width = 0;
|
par.width = 0;
|
||||||
par.height = 0;
|
par.height = 0;
|
||||||
par.smoothing_factor = 50;
|
par.smoothing_factor = 100;
|
||||||
par.scaling_factor = 100;
|
par.scaling_factor = 100;
|
||||||
//par.color_space = NULL; TODO Must set?
|
par.color_space = JCS_RGB;
|
||||||
//par.dct_method = NULL; TODO Must set?
|
par.dct_method = JDCT_ISLOW;
|
||||||
par.output_folder = NULL;
|
par.output_folder = NULL;
|
||||||
par.exif_copy = 0;
|
par.exif_copy = 0;
|
||||||
par.lossless = 0;
|
par.lossless = 0;
|
||||||
par.input_files_count = 0;
|
par.input_files_count = 0;
|
||||||
|
|
||||||
return par;
|
return par;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,9 +78,124 @@ void print_progress(int current, int max, char* message) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO Recheck
|
||||||
|
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--);
|
||||||
|
*p = '\0';
|
||||||
|
/* try make parent directory */
|
||||||
|
if(p != parent && mkpath(parent, mode) != 0)
|
||||||
|
return -1;
|
||||||
|
/* make this one if parent has been made */
|
||||||
|
if(mkdir(pathname, mode) == 0)
|
||||||
|
return 0;
|
||||||
|
/* if it already exists that is fine */
|
||||||
|
if(errno == EEXIST)
|
||||||
|
return 0;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
char* get_filename_with_extension(char* full_path) {
|
char* get_filename_with_extension(char* full_path) {
|
||||||
char* dest;
|
char* dest;
|
||||||
|
|
||||||
dest = strrchr(full_path, '/') + 1;
|
dest = strrchr(full_path, '/') + 1;
|
||||||
|
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void jcopy_markers_execute (j_decompress_ptr srcinfo, j_compress_ptr dstinfo) {
|
||||||
|
jpeg_saved_marker_ptr marker;
|
||||||
|
|
||||||
|
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;
|
||||||
|
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;
|
||||||
|
jpeg_write_marker(dstinfo, marker->marker,
|
||||||
|
marker->data, marker->data_length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cclt_compress_parameters parse_arguments(int argc, char* argv[]) {
|
||||||
|
|
||||||
|
//Initialize default params
|
||||||
|
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("CCLT - Caesium Command Line Tools - Version %s (Build: %d)\n", APP_VERSION, BUILD);
|
||||||
|
exit(0);
|
||||||
|
break;
|
||||||
|
case '?':
|
||||||
|
if (optopt == 'q' || optopt == 'o' || optopt == 's') {
|
||||||
|
fprintf (stderr, "Option -%c requires an argument.\n", optopt);
|
||||||
|
//Arguments without values
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
else if (isprint(optopt)) {
|
||||||
|
fprintf (stderr, "Unknown option `-%c'.\n", optopt);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ':':
|
||||||
|
fprintf(stderr, "Parameter expected.\n");
|
||||||
|
break;
|
||||||
|
case 'q':
|
||||||
|
parameters.quality = string_to_int(optarg);
|
||||||
|
break;
|
||||||
|
case 'e':
|
||||||
|
parameters.exif_copy = 1;
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
parameters.lossless = 1;
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
parameters.output_folder = optarg;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
parameters.scaling_factor = string_to_int(optarg);
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
print_help();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int i = 0;
|
||||||
|
parameters.input_files = (char**) malloc ((argc - optind) * sizeof (char*));
|
||||||
|
while (optind < argc) {
|
||||||
|
parameters.input_files[i] = (char*) malloc (strlen(argv[optind]) * sizeof(char)); //TODO Necessary??
|
||||||
|
parameters.input_files[i] = argv[optind];
|
||||||
|
parameters.input_files_count = i + 1;
|
||||||
|
optind++;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return parameters;
|
||||||
|
}
|
10
src/utils.h
10
src/utils.h
|
@ -1,8 +1,11 @@
|
||||||
#ifndef CCTL_UTILS
|
#ifndef CCLT_UTILS
|
||||||
#define CCTL_UTILS
|
#define CCLT_UTILS
|
||||||
|
|
||||||
#include <jpeglib.h>
|
#include <jpeglib.h>
|
||||||
|
|
||||||
|
#define APP_VERSION "1.9.9 BETA"
|
||||||
|
#define BUILD 20150515
|
||||||
|
|
||||||
typedef struct cclt_compress_parameters {
|
typedef struct cclt_compress_parameters {
|
||||||
int quality;
|
int quality;
|
||||||
int width;
|
int width;
|
||||||
|
@ -24,5 +27,8 @@ int string_to_int(char* in_string);
|
||||||
void print_help();
|
void print_help();
|
||||||
void print_progress(int current, int max, char* message);
|
void print_progress(int current, int max, char* message);
|
||||||
char* get_filename_with_extension(char* full_path);
|
char* get_filename_with_extension(char* full_path);
|
||||||
|
void jcopy_markers_execute (j_decompress_ptr srcinfo, j_compress_ptr dstinfo);
|
||||||
|
int mkpath(const char *pathname, mode_t mode);
|
||||||
|
cclt_compress_parameters parse_arguments(int argc, char* argv[]);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue