Initial
This commit is contained in:
parent
fd6e9c64e7
commit
4af0415e73
|
@ -3,8 +3,8 @@ project(caesiumclt)
|
||||||
|
|
||||||
# The version number.
|
# The version number.
|
||||||
set(VERSION_MAJOR 0)
|
set(VERSION_MAJOR 0)
|
||||||
set(VERSION_MINOR 10)
|
set(VERSION_MINOR 11)
|
||||||
set(VERSION_PATCH 2)
|
set(VERSION_PATCH 0)
|
||||||
|
|
||||||
configure_file(
|
configure_file(
|
||||||
"src/config.h.in"
|
"src/config.h.in"
|
||||||
|
|
|
@ -39,9 +39,9 @@ const char *get_error_message(int code)
|
||||||
case 9:
|
case 9:
|
||||||
return "Input files provided. Cannot mix them with a folder.";
|
return "Input files provided. Cannot mix them with a folder.";
|
||||||
case 10:
|
case 10:
|
||||||
return "-R is useless on files.";
|
return "-R has no effects on files.";
|
||||||
case 11:
|
case 11:
|
||||||
return "-S is useless without -R.";
|
return "-S has no effect without -R.";
|
||||||
case 12:
|
case 12:
|
||||||
return "Cannot set output folder inside the input one";
|
return "Cannot set output folder inside the input one";
|
||||||
|
|
||||||
|
|
11
src/helper.c
11
src/helper.c
|
@ -18,6 +18,7 @@ cclt_options parse_arguments(char **argv, cs_image_pars *options)
|
||||||
struct optparse_long longopts[] = {
|
struct optparse_long longopts[] = {
|
||||||
{"quality", 'q', OPTPARSE_REQUIRED},
|
{"quality", 'q', OPTPARSE_REQUIRED},
|
||||||
{"exif", 'e', OPTPARSE_NONE},
|
{"exif", 'e', OPTPARSE_NONE},
|
||||||
|
{"progressive", 'p', OPTPARSE_NONE},
|
||||||
{"output", 'o', OPTPARSE_REQUIRED},
|
{"output", 'o', OPTPARSE_REQUIRED},
|
||||||
{"recursive", 'R', OPTPARSE_NONE},
|
{"recursive", 'R', OPTPARSE_NONE},
|
||||||
{"keep-structure", 'S', OPTPARSE_NONE},
|
{"keep-structure", 'S', OPTPARSE_NONE},
|
||||||
|
@ -37,6 +38,8 @@ cclt_options parse_arguments(char **argv, cs_image_pars *options)
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
options->jpeg.exif_copy = true;
|
options->jpeg.exif_copy = true;
|
||||||
|
case 'p':
|
||||||
|
options->jpeg.progressive = false;
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
if (opts.optarg[strlen(opts.optarg) - 1] == '/' || opts.optarg[strlen(opts.optarg) - 1] == '\\') {
|
if (opts.optarg[strlen(opts.optarg) - 1] == '/' || opts.optarg[strlen(opts.optarg) - 1] == '\\') {
|
||||||
|
@ -76,7 +79,7 @@ cclt_options parse_arguments(char **argv, cs_image_pars *options)
|
||||||
while ((arg = optparse_arg(&opts))) {
|
while ((arg = optparse_arg(&opts))) {
|
||||||
if (folders_flag) {
|
if (folders_flag) {
|
||||||
display_error(WARNING, 8);
|
display_error(WARNING, 8);
|
||||||
continue;
|
break;
|
||||||
}
|
}
|
||||||
//Check if it's a directory and add its content
|
//Check if it's a directory and add its content
|
||||||
if (is_directory(arg)) {
|
if (is_directory(arg)) {
|
||||||
|
@ -155,9 +158,11 @@ int start_compression(cclt_options *options, cs_image_pars *parameters)
|
||||||
size_t index = strspn(options->input_folder, options->input_files[i]) + 1;
|
size_t index = strspn(options->input_folder, options->input_files[i]) + 1;
|
||||||
size_t size = strlen(options->input_files[i]) - index - strlen(filename);
|
size_t size = strlen(options->input_files[i]) - index - strlen(filename);
|
||||||
char output_full_folder[strlen(options->output_folder) + size + 1];
|
char output_full_folder[strlen(options->output_folder) + size + 1];
|
||||||
snprintf(output_full_folder, strlen(options->output_folder) + size + 1, "%s%s", options->output_folder, &options->input_files[i][index]);
|
snprintf(output_full_folder, strlen(options->output_folder) + size + 1, "%s%s", options->output_folder,
|
||||||
|
&options->input_files[i][index]);
|
||||||
output_full_path = malloc((strlen(output_full_folder) + strlen(filename) + 1) * sizeof(char));
|
output_full_path = malloc((strlen(output_full_folder) + strlen(filename) + 1) * sizeof(char));
|
||||||
snprintf(output_full_path, strlen(output_full_folder) + strlen(filename) + 1, "%s%s", output_full_folder, filename);
|
snprintf(output_full_path, strlen(output_full_folder) + strlen(filename) + 1, "%s%s", output_full_folder,
|
||||||
|
filename);
|
||||||
mkpath(output_full_folder);
|
mkpath(output_full_folder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,11 +99,6 @@ int optparse(struct optparse *options, const char *optstring)
|
||||||
int type = argtype(optstring, option[0]);
|
int type = argtype(optstring, option[0]);
|
||||||
char *next = options->argv[options->optind + 1];
|
char *next = options->argv[options->optind + 1];
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case -1: {
|
|
||||||
options->optind++;
|
|
||||||
char str[2] = {option[0]};
|
|
||||||
return opterror(options, MSG_INVALID, str);
|
|
||||||
}
|
|
||||||
case OPTPARSE_NONE:
|
case OPTPARSE_NONE:
|
||||||
if (option[1]) {
|
if (option[1]) {
|
||||||
options->subopt++;
|
options->subopt++;
|
||||||
|
@ -134,8 +129,13 @@ int optparse(struct optparse *options, const char *optstring)
|
||||||
else
|
else
|
||||||
options->optarg = 0;
|
options->optarg = 0;
|
||||||
return option[0];
|
return option[0];
|
||||||
|
default:
|
||||||
|
case -1: {
|
||||||
|
options->optind++;
|
||||||
|
char str[2] = {option[0]};
|
||||||
|
return opterror(options, MSG_INVALID, str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *optparse_arg(struct optparse *options)
|
char *optparse_arg(struct optparse *options)
|
||||||
|
|
177
src/utils.c
177
src/utils.c
|
@ -19,6 +19,7 @@ void print_help()
|
||||||
"Options:\n"
|
"Options:\n"
|
||||||
"\t-q, --quality\t\tset output file quality between [0-100], 0 for optimization\n"
|
"\t-q, --quality\t\tset output file quality between [0-100], 0 for optimization\n"
|
||||||
"\t-e, --exif\t\tkeeps EXIF info during compression\n"
|
"\t-e, --exif\t\tkeeps EXIF info during compression\n"
|
||||||
|
"\t-p, --progressive\t\toutputs a progressive JPEG\n"
|
||||||
"\t-o, --output\t\toutput folder\n"
|
"\t-o, --output\t\toutput folder\n"
|
||||||
"\t-R, --recursive\t\tif input is a folder, scan subfolders too\n"
|
"\t-R, --recursive\t\tif input is a folder, scan subfolders too\n"
|
||||||
"\t-S, --keep-structure\tkeep the folder structure, use with -R\n"
|
"\t-S, --keep-structure\tkeep the folder structure, use with -R\n"
|
||||||
|
@ -30,18 +31,18 @@ void print_help()
|
||||||
bool is_directory(const char *path)
|
bool is_directory(const char *path)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
tinydir_dir dir;
|
tinydir_dir dir;
|
||||||
|
|
||||||
return tinydir_open(&dir, path) != -1;
|
return tinydir_open(&dir, path) != -1;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
tinydir_file file;
|
tinydir_file file;
|
||||||
|
|
||||||
if (tinydir_file_open(&file, path) == -1) {
|
if (tinydir_file_open(&file, path) == -1) {
|
||||||
display_error(ERROR, 6);
|
display_error(ERROR, 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (bool) file.is_dir;
|
return (bool) file.is_dir;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,10 +63,10 @@ int scan_folder(const char *directory, cclt_options *options, bool recursive)
|
||||||
} else {
|
} else {
|
||||||
options->input_files = realloc(options->input_files, (options->files_count + 1) * sizeof(char *));
|
options->input_files = realloc(options->input_files, (options->files_count + 1) * sizeof(char *));
|
||||||
options->input_files[options->files_count] = malloc((strlen(file.path) + 1) * sizeof(char));
|
options->input_files[options->files_count] = malloc((strlen(file.path) + 1) * sizeof(char));
|
||||||
snprintf(options->input_files[options->files_count],
|
snprintf(options->input_files[options->files_count],
|
||||||
strlen(file.path) + 1, "%s", file.path);
|
strlen(file.path) + 1, "%s", file.path);
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
options->input_files[options->files_count] = str_replace(options->input_files[options->files_count], "/", "\\");
|
options->input_files[options->files_count] = str_replace(options->input_files[options->files_count], "/", "\\");
|
||||||
#endif
|
#endif
|
||||||
options->files_count++;
|
options->files_count++;
|
||||||
n++;
|
n++;
|
||||||
|
@ -107,13 +108,11 @@ char *get_filename(char *full_path)
|
||||||
|
|
||||||
//Get just the filename
|
//Get just the filename
|
||||||
tofree = strdup(full_path);
|
tofree = strdup(full_path);
|
||||||
//TODO change to strncpy
|
snprintf(tofree, strlen(full_path) + 1, "%s", full_path);
|
||||||
strcpy(tofree, full_path);
|
|
||||||
//TODO Windows?
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
while ((token = strsep(&tofree, "\\")) != NULL) {
|
while ((token = strsep(&tofree, "\\")) != NULL) {
|
||||||
#else
|
#else
|
||||||
while ((token = strsep(&tofree, "/")) != NULL) {
|
while ((token = strsep(&tofree, "/")) != NULL) {
|
||||||
#endif
|
#endif
|
||||||
if (tofree == NULL) {
|
if (tofree == NULL) {
|
||||||
break;
|
break;
|
||||||
|
@ -127,15 +126,15 @@ char *get_filename(char *full_path)
|
||||||
|
|
||||||
off_t get_file_size(const char *path)
|
off_t get_file_size(const char *path)
|
||||||
{
|
{
|
||||||
FILE *f = fopen(path, "rb");
|
FILE *f = fopen(path, "rb");
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
display_error(ERROR, 7);
|
display_error(ERROR, 7);
|
||||||
}
|
}
|
||||||
fseek(f, 0, SEEK_END);
|
fseek(f, 0, SEEK_END);
|
||||||
unsigned long len = (unsigned long)ftell(f);
|
off_t len = ftell(f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *get_human_size(off_t size)
|
char *get_human_size(off_t size)
|
||||||
|
@ -160,86 +159,86 @@ char *get_human_size(off_t size)
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
char *str_replace(char *orig, char *rep, char *with) {
|
char *str_replace(char *orig, char *rep, char *with) {
|
||||||
char *result; // the return string
|
char *result; // the return string
|
||||||
char *ins; // the next insert point
|
char *ins; // the next insert point
|
||||||
char *tmp; // varies
|
char *tmp; // varies
|
||||||
int len_rep; // length of rep (the string to remove)
|
int len_rep; // length of rep (the string to remove)
|
||||||
int len_with; // length of with (the string to replace rep with)
|
int len_with; // length of with (the string to replace rep with)
|
||||||
int len_front; // distance between rep and end of last rep
|
int len_front; // distance between rep and end of last rep
|
||||||
int count; // number of replacements
|
int count; // number of replacements
|
||||||
|
|
||||||
if (!orig || !rep)
|
if (!orig || !rep)
|
||||||
return NULL;
|
return NULL;
|
||||||
len_rep = strlen(rep);
|
len_rep = strlen(rep);
|
||||||
if (len_rep == 0)
|
if (len_rep == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (!with)
|
if (!with)
|
||||||
with = "";
|
with = "";
|
||||||
len_with = strlen(with);
|
len_with = strlen(with);
|
||||||
|
|
||||||
ins = orig;
|
ins = orig;
|
||||||
for (count = 0; tmp = strstr(ins, rep); ++count) {
|
for (count = 0; tmp = strstr(ins, rep); ++count) {
|
||||||
ins = tmp + len_rep;
|
ins = tmp + len_rep;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = result = malloc(strlen(orig) + (len_with - len_rep) * count + 1);
|
tmp = result = malloc(strlen(orig) + (len_with - len_rep) * count + 1);
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
while (count--) {
|
while (count--) {
|
||||||
ins = strstr(orig, rep);
|
ins = strstr(orig, rep);
|
||||||
len_front = ins - orig;
|
len_front = ins - orig;
|
||||||
tmp = strncpy(tmp, orig, len_front) + len_front;
|
tmp = strncpy(tmp, orig, len_front) + len_front;
|
||||||
tmp = strcpy(tmp, with) + len_with;
|
tmp = strcpy(tmp, with) + len_with;
|
||||||
orig += len_front + len_rep;
|
orig += len_front + len_rep;
|
||||||
}
|
}
|
||||||
strcpy(tmp, orig);
|
strcpy(tmp, orig);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *strsep (char **stringp, const char *delim)
|
char *strsep (char **stringp, const char *delim)
|
||||||
{
|
{
|
||||||
char *begin, *end;
|
char *begin, *end;
|
||||||
|
|
||||||
begin = *stringp;
|
begin = *stringp;
|
||||||
if (begin == NULL)
|
if (begin == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* A frequent case is when the delimiter string contains only one
|
/* A frequent case is when the delimiter string contains only one
|
||||||
character. Here we don't need to call the expensive `strpbrk'
|
character. Here we don't need to call the expensive `strpbrk'
|
||||||
function and instead work using `strchr'. */
|
function and instead work using `strchr'. */
|
||||||
if (delim[0] == '\0' || delim[1] == '\0')
|
if (delim[0] == '\0' || delim[1] == '\0')
|
||||||
{
|
{
|
||||||
char ch = delim[0];
|
char ch = delim[0];
|
||||||
|
|
||||||
if (ch == '\0')
|
if (ch == '\0')
|
||||||
end = NULL;
|
end = NULL;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (*begin == ch)
|
if (*begin == ch)
|
||||||
end = begin;
|
end = begin;
|
||||||
else if (*begin == '\0')
|
else if (*begin == '\0')
|
||||||
end = NULL;
|
end = NULL;
|
||||||
else
|
else
|
||||||
end = strchr (begin + 1, ch);
|
end = strchr (begin + 1, ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* Find the end of the token. */
|
/* Find the end of the token. */
|
||||||
end = strpbrk (begin, delim);
|
end = strpbrk (begin, delim);
|
||||||
|
|
||||||
if (end)
|
if (end)
|
||||||
{
|
{
|
||||||
/* Terminate the token and set *STRINGP past NUL character. */
|
/* Terminate the token and set *STRINGP past NUL character. */
|
||||||
*end++ = '\0';
|
*end++ = '\0';
|
||||||
*stringp = end;
|
*stringp = end;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* No more delimiters; this is the last token. */
|
/* No more delimiters; this is the last token. */
|
||||||
*stringp = NULL;
|
*stringp = NULL;
|
||||||
|
|
||||||
return begin;
|
return begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue