Start with basic PNG support

Also changed function structure
This commit is contained in:
Matteo Paonessa 2015-07-26 13:36:22 +02:00
parent 26e6802d4c
commit bf2953de2b
17 changed files with 602 additions and 442 deletions

2
configure vendored
View File

@ -3854,6 +3854,8 @@ fi
ac_config_files="$ac_config_files Makefile src/Makefile"
#TODO Check for turbojpeg instead
# Check whether --with-libjpeg was given.
if test "${with_libjpeg+set}" = set; then :

View File

@ -15,6 +15,8 @@ AC_CONFIG_FILES([
src/Makefile
])
#TODO Check for turbojpeg instead
AC_ARG_WITH(libjpeg, [ --libjpeg=DIR libjpeg is installed in ],
[if test $withval != yes; then
jpeginfo_cv_libjpeg=$withval

View File

@ -1,4 +1,4 @@
bin_PROGRAMS = caesiumclt
caesiumclt_SOURCES = main.c utils.c lossless.c compress.c
caesiumclt_SOURCES = main.c jpeg.c compresshelper.c utils.c png.c
caesiumclt_CFLAGS = -Wall -D_FILE_OFFSET_BITS=64 -std=c99
caesiumclt_LDADD = -ljpeg -lturbojpeg -lm
caesiumclt_LDADD = -ljpeg -lturbojpeg -lm -lz -lpng

View File

@ -99,8 +99,8 @@ CONFIG_CLEAN_VPATH_FILES =
am__installdirs = "$(DESTDIR)$(bindir)"
PROGRAMS = $(bin_PROGRAMS)
am_caesiumclt_OBJECTS = caesiumclt-main.$(OBJEXT) \
caesiumclt-utils.$(OBJEXT) caesiumclt-lossless.$(OBJEXT) \
caesiumclt-compress.$(OBJEXT)
caesiumclt-jpeg.$(OBJEXT) caesiumclt-compresshelper.$(OBJEXT) \
caesiumclt-utils.$(OBJEXT) caesiumclt-png.$(OBJEXT)
caesiumclt_OBJECTS = $(am_caesiumclt_OBJECTS)
caesiumclt_DEPENDENCIES =
caesiumclt_LINK = $(CCLD) $(caesiumclt_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
@ -117,7 +117,6 @@ AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/tools/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
@ -252,9 +251,9 @@ target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
caesiumclt_SOURCES = main.c utils.c lossless.c compress.c
caesiumclt_SOURCES = main.c jpeg.c compresshelper.c utils.c png.c
caesiumclt_CFLAGS = -Wall -D_FILE_OFFSET_BITS=64 -std=c99
caesiumclt_LDADD = -ljpeg -lturbojpeg -lm
caesiumclt_LDADD = -ljpeg -lturbojpeg -lm -lz -lpng
all: all-am
.SUFFIXES:
@ -341,9 +340,10 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/caesiumclt-compress.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/caesiumclt-lossless.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/caesiumclt-compresshelper.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/caesiumclt-jpeg.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/caesiumclt-main.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/caesiumclt-png.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/caesiumclt-utils.Po@am__quote@
.c.o:
@ -374,6 +374,34 @@ caesiumclt-main.obj: main.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(caesiumclt_CFLAGS) $(CFLAGS) -c -o caesiumclt-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi`
caesiumclt-jpeg.o: jpeg.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(caesiumclt_CFLAGS) $(CFLAGS) -MT caesiumclt-jpeg.o -MD -MP -MF $(DEPDIR)/caesiumclt-jpeg.Tpo -c -o caesiumclt-jpeg.o `test -f 'jpeg.c' || echo '$(srcdir)/'`jpeg.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/caesiumclt-jpeg.Tpo $(DEPDIR)/caesiumclt-jpeg.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='jpeg.c' object='caesiumclt-jpeg.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(caesiumclt_CFLAGS) $(CFLAGS) -c -o caesiumclt-jpeg.o `test -f 'jpeg.c' || echo '$(srcdir)/'`jpeg.c
caesiumclt-jpeg.obj: jpeg.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(caesiumclt_CFLAGS) $(CFLAGS) -MT caesiumclt-jpeg.obj -MD -MP -MF $(DEPDIR)/caesiumclt-jpeg.Tpo -c -o caesiumclt-jpeg.obj `if test -f 'jpeg.c'; then $(CYGPATH_W) 'jpeg.c'; else $(CYGPATH_W) '$(srcdir)/jpeg.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/caesiumclt-jpeg.Tpo $(DEPDIR)/caesiumclt-jpeg.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='jpeg.c' object='caesiumclt-jpeg.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(caesiumclt_CFLAGS) $(CFLAGS) -c -o caesiumclt-jpeg.obj `if test -f 'jpeg.c'; then $(CYGPATH_W) 'jpeg.c'; else $(CYGPATH_W) '$(srcdir)/jpeg.c'; fi`
caesiumclt-compresshelper.o: compresshelper.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(caesiumclt_CFLAGS) $(CFLAGS) -MT caesiumclt-compresshelper.o -MD -MP -MF $(DEPDIR)/caesiumclt-compresshelper.Tpo -c -o caesiumclt-compresshelper.o `test -f 'compresshelper.c' || echo '$(srcdir)/'`compresshelper.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/caesiumclt-compresshelper.Tpo $(DEPDIR)/caesiumclt-compresshelper.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='compresshelper.c' object='caesiumclt-compresshelper.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(caesiumclt_CFLAGS) $(CFLAGS) -c -o caesiumclt-compresshelper.o `test -f 'compresshelper.c' || echo '$(srcdir)/'`compresshelper.c
caesiumclt-compresshelper.obj: compresshelper.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(caesiumclt_CFLAGS) $(CFLAGS) -MT caesiumclt-compresshelper.obj -MD -MP -MF $(DEPDIR)/caesiumclt-compresshelper.Tpo -c -o caesiumclt-compresshelper.obj `if test -f 'compresshelper.c'; then $(CYGPATH_W) 'compresshelper.c'; else $(CYGPATH_W) '$(srcdir)/compresshelper.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/caesiumclt-compresshelper.Tpo $(DEPDIR)/caesiumclt-compresshelper.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='compresshelper.c' object='caesiumclt-compresshelper.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(caesiumclt_CFLAGS) $(CFLAGS) -c -o caesiumclt-compresshelper.obj `if test -f 'compresshelper.c'; then $(CYGPATH_W) 'compresshelper.c'; else $(CYGPATH_W) '$(srcdir)/compresshelper.c'; fi`
caesiumclt-utils.o: utils.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(caesiumclt_CFLAGS) $(CFLAGS) -MT caesiumclt-utils.o -MD -MP -MF $(DEPDIR)/caesiumclt-utils.Tpo -c -o caesiumclt-utils.o `test -f 'utils.c' || echo '$(srcdir)/'`utils.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/caesiumclt-utils.Tpo $(DEPDIR)/caesiumclt-utils.Po
@ -388,33 +416,19 @@ caesiumclt-utils.obj: utils.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(caesiumclt_CFLAGS) $(CFLAGS) -c -o caesiumclt-utils.obj `if test -f 'utils.c'; then $(CYGPATH_W) 'utils.c'; else $(CYGPATH_W) '$(srcdir)/utils.c'; fi`
caesiumclt-lossless.o: lossless.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(caesiumclt_CFLAGS) $(CFLAGS) -MT caesiumclt-lossless.o -MD -MP -MF $(DEPDIR)/caesiumclt-lossless.Tpo -c -o caesiumclt-lossless.o `test -f 'lossless.c' || echo '$(srcdir)/'`lossless.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/caesiumclt-lossless.Tpo $(DEPDIR)/caesiumclt-lossless.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lossless.c' object='caesiumclt-lossless.o' libtool=no @AMDEPBACKSLASH@
caesiumclt-png.o: png.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(caesiumclt_CFLAGS) $(CFLAGS) -MT caesiumclt-png.o -MD -MP -MF $(DEPDIR)/caesiumclt-png.Tpo -c -o caesiumclt-png.o `test -f 'png.c' || echo '$(srcdir)/'`png.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/caesiumclt-png.Tpo $(DEPDIR)/caesiumclt-png.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='png.c' object='caesiumclt-png.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(caesiumclt_CFLAGS) $(CFLAGS) -c -o caesiumclt-lossless.o `test -f 'lossless.c' || echo '$(srcdir)/'`lossless.c
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(caesiumclt_CFLAGS) $(CFLAGS) -c -o caesiumclt-png.o `test -f 'png.c' || echo '$(srcdir)/'`png.c
caesiumclt-lossless.obj: lossless.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(caesiumclt_CFLAGS) $(CFLAGS) -MT caesiumclt-lossless.obj -MD -MP -MF $(DEPDIR)/caesiumclt-lossless.Tpo -c -o caesiumclt-lossless.obj `if test -f 'lossless.c'; then $(CYGPATH_W) 'lossless.c'; else $(CYGPATH_W) '$(srcdir)/lossless.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/caesiumclt-lossless.Tpo $(DEPDIR)/caesiumclt-lossless.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lossless.c' object='caesiumclt-lossless.obj' libtool=no @AMDEPBACKSLASH@
caesiumclt-png.obj: png.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(caesiumclt_CFLAGS) $(CFLAGS) -MT caesiumclt-png.obj -MD -MP -MF $(DEPDIR)/caesiumclt-png.Tpo -c -o caesiumclt-png.obj `if test -f 'png.c'; then $(CYGPATH_W) 'png.c'; else $(CYGPATH_W) '$(srcdir)/png.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/caesiumclt-png.Tpo $(DEPDIR)/caesiumclt-png.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='png.c' object='caesiumclt-png.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(caesiumclt_CFLAGS) $(CFLAGS) -c -o caesiumclt-lossless.obj `if test -f 'lossless.c'; then $(CYGPATH_W) 'lossless.c'; else $(CYGPATH_W) '$(srcdir)/lossless.c'; fi`
caesiumclt-compress.o: compress.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(caesiumclt_CFLAGS) $(CFLAGS) -MT caesiumclt-compress.o -MD -MP -MF $(DEPDIR)/caesiumclt-compress.Tpo -c -o caesiumclt-compress.o `test -f 'compress.c' || echo '$(srcdir)/'`compress.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/caesiumclt-compress.Tpo $(DEPDIR)/caesiumclt-compress.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='compress.c' object='caesiumclt-compress.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(caesiumclt_CFLAGS) $(CFLAGS) -c -o caesiumclt-compress.o `test -f 'compress.c' || echo '$(srcdir)/'`compress.c
caesiumclt-compress.obj: compress.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(caesiumclt_CFLAGS) $(CFLAGS) -MT caesiumclt-compress.obj -MD -MP -MF $(DEPDIR)/caesiumclt-compress.Tpo -c -o caesiumclt-compress.obj `if test -f 'compress.c'; then $(CYGPATH_W) 'compress.c'; else $(CYGPATH_W) '$(srcdir)/compress.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/caesiumclt-compress.Tpo $(DEPDIR)/caesiumclt-compress.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='compress.c' object='caesiumclt-compress.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(caesiumclt_CFLAGS) $(CFLAGS) -c -o caesiumclt-compress.obj `if test -f 'compress.c'; then $(CYGPATH_W) 'compress.c'; else $(CYGPATH_W) '$(srcdir)/compress.c'; fi`
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(caesiumclt_CFLAGS) $(CFLAGS) -c -o caesiumclt-png.obj `if test -f 'png.c'; then $(CYGPATH_W) 'png.c'; else $(CYGPATH_W) '$(srcdir)/png.c'; fi`
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique

View File

@ -1,98 +0,0 @@
#include <setjmp.h>
#include <stdio.h>
#include <jpeglib.h>
#include <turbojpeg.h>
#include <stdlib.h>
#include <math.h>
#include "compress.h"
#include "utils.h"
//TODO Error handling
void cclt_compress(char* output_file, unsigned char* image_buffer, cclt_compress_parameters* pars) {
FILE* fp;
tjhandle tjCompressHandle;
unsigned char* output_buffer;
int status;
unsigned long output_size = 0;
fp = fopen(output_file, "wb");
//Check for errors
//TODO Use UNIX error messages
if (fp == NULL) {
printf("INPUT: Failed to open output \"%s\"\n", output_file);
return;
}
output_buffer = NULL;
tjCompressHandle = tjInitCompress();
status = 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, 1, output_size, fp);
fclose(fp);
tjDestroy(tjCompressHandle);
tjFree(output_buffer);
}
unsigned char* cclt_decompress(char* fileName, cclt_compress_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;
//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 = tjDecompressHeader2(tjDecompressHandle, sourceJpegBuffer, sourceJpegBufferSize, &fileWidth, &fileHeight, &jpegSubsamp);
pars->width = ceil(fileWidth * ((double) pars->scaling_factor / 100));
pars->height = ceil(fileHeight * ((double) pars->scaling_factor / 100));
pars->subsample = jpegSubsamp;
if (pars->subsample == TJSAMP_GRAY) {
pars->color_space = TJPF_GRAY;
}
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,
TJFLAG_ACCURATEDCT);
tjDestroy(tjDecompressHandle);
return temp;
}

View File

@ -1,9 +0,0 @@
#ifndef CCLT_COMPRESS
#define CCLT_COMPRESS
#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

114
src/compresshelper.c Normal file
View File

@ -0,0 +1,114 @@
#include <setjmp.h>
#include <stdio.h>
#include <jpeglib.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <turbojpeg.h>
#include <getopt.h>
#include <ctype.h>
#include "utils.h"
#include "jpeg.h"
cclt_compress_parameters initialize_compression_parameters() {
cclt_compress_parameters par;
par.quality = 0;
par.width = 0;
par.height = 0;
par.scaling_factor = 100;
par.color_space = TJPF_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;
return par;
}
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;
case 'R':
parameters.recursive = 1;
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;
}
void cclt_compress_routine(char* input, char* output, cclt_compress_parameters* pars) {
enum image_type type = detect_image_type(input);
if (type == JPEG) {
cclt_compress(output, cclt_decompress(input, pars), pars);
cclt_optimize(output, output, pars->exif_copy, input);
} else if (type == PNG) {
printf("PNG detected. Not implemented yet.\n");
} else if (type == GIF) {
printf("GIF detected. Not implemented yet.\n");
} else {
return;
}
}

10
src/compresshelper.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef CCLT_COMPRESSHELPER
#define CCLT_COMPRESSHELPER
#include "utils.h"
cclt_compress_parameters initialize_compression_parameters();
cclt_compress_parameters parse_arguments(int argc, char* argv[]);
void cclt_compress_routine(char* input, char* output, cclt_compress_parameters* pars);
#endif

234
src/jpeg.c Normal file
View File

@ -0,0 +1,234 @@
#include <setjmp.h>
#include <stdio.h>
#include <jpeglib.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <turbojpeg.h>
#include <math.h>
#include "jpeg.h"
#include "utils.h"
//TODO Error handling
struct jpeg_decompress_struct cclt_get_markers(char* input) {
FILE* fp;
struct jpeg_decompress_struct einfo;
struct jpeg_error_mgr eerr;
einfo.err = jpeg_std_error(&eerr);
jpeg_create_decompress(&einfo);
//Open the input file
fp = fopen(input, "r");
//Check for errors
//TODO Use UNIX error messages
if (fp == NULL) {
printf("INPUT: Failed to open exif file \"%s\"\n", input);
exit(-13);
}
//Create the IO istance for the input file
jpeg_stdio_src(&einfo, fp);
//Save EXIF info
for (int m = 0; m < 16; m++) {
jpeg_save_markers(&einfo, JPEG_APP0 + m, 0xFFFF);
}
jpeg_read_header(&einfo, TRUE);
fclose(fp);
return einfo;
}
int cclt_optimize(char* input_file, char* output_file, int exif_flag, char* exif_src) {
//File pointer for both input and output
FILE* fp;
//Those will hold the input/output structs
struct jpeg_decompress_struct srcinfo;
struct jpeg_compress_struct dstinfo;
//Error handling
struct jpeg_error_mgr jsrcerr, jdsterr;
//Input/Output array coefficents
jvirt_barray_ptr* src_coef_arrays;
jvirt_barray_ptr* dst_coef_arrays;
//Set errors and create the compress/decompress istances
srcinfo.err = jpeg_std_error(&jsrcerr);
jpeg_create_decompress(&srcinfo);
dstinfo.err = jpeg_std_error(&jdsterr);
jpeg_create_compress(&dstinfo);
//Open the input file
fp = fopen(input_file, "r");
//Check for errors
//TODO Use UNIX error messages
if (fp == NULL) {
printf("INPUT: Failed to open file \"%s\"\n", input_file);
return -1;
}
//Create the IO istance for the input file
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
(void) jpeg_read_header(&srcinfo, TRUE);
//Read input coefficents
src_coef_arrays = jpeg_read_coefficients(&srcinfo);
//jcopy_markers_setup(&srcinfo, copyoption);
//Copy parameters
jpeg_copy_critical_parameters(&srcinfo, &dstinfo);
//Set coefficents array to be the same
dst_coef_arrays = src_coef_arrays;
//We don't need the input file anymore
fclose(fp);
//Open the output one instead
fp = fopen(output_file, "w+");
//Check for errors
//TODO Use UNIX error messages
if (fp == NULL) {
printf("OUTPUT: Failed to open file \"%s\"\n", output_file);
return -2;
}
//CRITICAL - This is the optimization step
dstinfo.optimize_coding = TRUE;
//Progressive
jpeg_simple_progression(&dstinfo);
//Set the output file parameters
jpeg_stdio_dest(&dstinfo, fp);
//Actually write the coefficents
jpeg_write_coefficients(&dstinfo, dst_coef_arrays);
//Write EXIF
if (exif_flag == 1) {
if (strcmp(input_file, exif_src) == 0) {
jcopy_markers_execute(&srcinfo, &dstinfo);
} else {
//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
jpeg_finish_compress(&dstinfo);
jpeg_destroy_compress(&dstinfo);
(void) jpeg_finish_decompress(&srcinfo);
jpeg_destroy_decompress(&srcinfo);
//Close the output file
fclose(fp);
return 0;
}
void cclt_compress(char* output_file, unsigned char* image_buffer, cclt_compress_parameters* pars) {
FILE* fp;
tjhandle tjCompressHandle;
unsigned char* output_buffer;
int status;
unsigned long output_size = 0;
fp = fopen(output_file, "wb");
//Check for errors
//TODO Use UNIX error messages
if (fp == NULL) {
printf("INPUT: Failed to open output \"%s\"\n", output_file);
return;
}
output_buffer = NULL;
tjCompressHandle = tjInitCompress();
status = 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, 1, output_size, fp);
fclose(fp);
tjDestroy(tjCompressHandle);
tjFree(output_buffer);
}
unsigned char* cclt_decompress(char* fileName, cclt_compress_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;
//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 = tjDecompressHeader2(tjDecompressHandle, sourceJpegBuffer, sourceJpegBufferSize, &fileWidth, &fileHeight, &jpegSubsamp);
pars->width = ceil(fileWidth * ((double) pars->scaling_factor / 100));
pars->height = ceil(fileHeight * ((double) pars->scaling_factor / 100));
pars->subsample = jpegSubsamp;
if (pars->subsample == TJSAMP_GRAY) {
pars->color_space = TJPF_GRAY;
}
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,
TJFLAG_ACCURATEDCT);
tjDestroy(tjDecompressHandle);
return temp;
}

15
src/jpeg.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef CCLT_JPEG
#define CCLT_JPEG
#include <jpeglib.h>
#include "utils.h"
int cclt_optimize(char* input_file, char* output_file, int exif_flag, char* exif_src);
struct jpeg_decompress_struct cclt_get_markers(char* input);
void cclt_compress(char* output_file, unsigned char* image_buffer, cclt_compress_parameters* pars);
unsigned char* cclt_decompress(char* fileName, cclt_compress_parameters* pars);
void jcopy_markers_execute (j_decompress_ptr srcinfo, j_compress_ptr dstinfo);
#endif

View File

@ -1,143 +0,0 @@
#include <setjmp.h>
#include <stdio.h>
#include <jpeglib.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include "lossless.h"
#include "utils.h"
struct jpeg_decompress_struct cclt_get_markers(char* input) {
FILE* fp;
struct jpeg_decompress_struct einfo;
struct jpeg_error_mgr eerr;
einfo.err = jpeg_std_error(&eerr);
jpeg_create_decompress(&einfo);
//Open the input file
fp = fopen(input, "r");
//Check for errors
//TODO Use UNIX error messages
if (fp == NULL) {
printf("INPUT: Failed to open exif file \"%s\"\n", input);
exit(-13);
}
//Create the IO istance for the input file
jpeg_stdio_src(&einfo, fp);
//Save EXIF info
for (int m = 0; m < 16; m++) {
jpeg_save_markers(&einfo, JPEG_APP0 + m, 0xFFFF);
}
jpeg_read_header(&einfo, TRUE);
fclose(fp);
return einfo;
}
int cclt_optimize(char* input_file, char* output_file, int exif_flag, char* exif_src) {
//File pointer for both input and output
FILE* fp;
//Those will hold the input/output structs
struct jpeg_decompress_struct srcinfo;
struct jpeg_compress_struct dstinfo;
//Error handling
struct jpeg_error_mgr jsrcerr, jdsterr;
//Input/Output array coefficents
jvirt_barray_ptr* src_coef_arrays;
jvirt_barray_ptr* dst_coef_arrays;
//Set errors and create the compress/decompress istances
srcinfo.err = jpeg_std_error(&jsrcerr);
jpeg_create_decompress(&srcinfo);
dstinfo.err = jpeg_std_error(&jdsterr);
jpeg_create_compress(&dstinfo);
//Open the input file
fp = fopen(input_file, "r");
//Check for errors
//TODO Use UNIX error messages
if (fp == NULL) {
printf("INPUT: Failed to open file \"%s\"\n", input_file);
return -1;
}
//Create the IO istance for the input file
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
(void) jpeg_read_header(&srcinfo, TRUE);
//Read input coefficents
src_coef_arrays = jpeg_read_coefficients(&srcinfo);
//jcopy_markers_setup(&srcinfo, copyoption);
//Copy parameters
jpeg_copy_critical_parameters(&srcinfo, &dstinfo);
//Set coefficents array to be the same
dst_coef_arrays = src_coef_arrays;
//We don't need the input file anymore
fclose(fp);
//Open the output one instead
fp = fopen(output_file, "w+");
//Check for errors
//TODO Use UNIX error messages
if (fp == NULL) {
printf("OUTPUT: Failed to open file \"%s\"\n", output_file);
return -2;
}
//CRITICAL - This is the optimization step
dstinfo.optimize_coding = TRUE;
//Progressive
jpeg_simple_progression(&dstinfo);
//Set the output file parameters
jpeg_stdio_dest(&dstinfo, fp);
//Actually write the coefficents
jpeg_write_coefficients(&dstinfo, dst_coef_arrays);
//Write EXIF
if (exif_flag == 1) {
if (strcmp(input_file, exif_src) == 0) {
jcopy_markers_execute(&srcinfo, &dstinfo);
} else {
//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
jpeg_finish_compress(&dstinfo);
jpeg_destroy_compress(&dstinfo);
(void) jpeg_finish_decompress(&srcinfo);
jpeg_destroy_decompress(&srcinfo);
//Close the output file
fclose(fp);
return 0;
}

View File

@ -1,7 +0,0 @@
#ifndef CCLT_LOSSLESS
#define CCLT_LOSSLESS
int cclt_optimize(char* input_file, char* output_file, int exif_flag, char* exif_src);
struct jpeg_decompress_struct cclt_get_markers(char* input);
#endif

View File

@ -9,19 +9,19 @@
#include <sys/stat.h>
#include <sys/types.h>
#include "lossless.h"
#include "compress.h"
#include "jpeg.h"
#include "compresshelper.h"
#include "utils.h"
/* PARAMETERS:
-q quality v
-e exif v
-o output folder v
-v version v
-l lossless v
-s scale v
-h help v
-R recursive
-q quality v
-e exif v
-o output folder v
-v version v
-l lossless v
-s scale v
-h help v
-R recursive
*/
@ -64,43 +64,43 @@ void cclt_start(char** input_files, int n, char* output_folder, cclt_compress_pa
//Get input stats
status = stat(input_files[i], &st_buf);
if (status != 0) {
fprintf(stderr, "Failed to get input file stats. Aborting.\n");
if (status != 0) {
fprintf(stderr, "Failed to get input file stats. Aborting.\n");
exit(-11);
}
}
//Check if we ran into a folder
//TODO Check symlinks too
if (S_ISDIR (st_buf.st_mode) && recursive == 0) {
if (S_ISDIR (st_buf.st_mode) && recursive == 0) {
//Folder found, but we don't need it here
i++;
continue;
} else if (S_ISDIR (st_buf.st_mode) && recursive != 0) {
//Folder found, we need to get into it
i++;
continue;
} else if (S_ISDIR (st_buf.st_mode) && recursive != 0) {
//Folder found, we need to get into it
/*
/*
1. Scan the entire folder input_files[i]
2. Get a new array containing all the files and folders
3. Set the output folder to be one step deeper
3. Call cclt_start(new_list, new folder, same, same, same)
*/
*/
//TODO malloc?
//char** new_files = (char**) malloc(256 * sizeof(char*));
//new_files = scan_folder(input_files[i], 0);
//cclt_start(new_files, output_folder, pars, i_t_size, o_t_size);
//i++;
//TODO Remove this after this funcion is fully completed
//free(new_files);
continue;
}
//cclt_start(new_files, output_folder, pars, i_t_size, o_t_size);
//i++;
//TODO Remove this after this funcion is fully completed
//free(new_files);
continue;
}
//Get input file size
i_size = st_buf.st_size;
*(i_t_size) += i_size;
//Get input file size
i_size = st_buf.st_size;
*(i_t_size) += i_size;
//TODO Do we want a more verbose output?
fprintf(stdout, "Compressing: %s -> %s\n", input_files[i], output_filename);
@ -113,15 +113,15 @@ void cclt_start(char** input_files, int n, char* output_folder, cclt_compress_pa
//Get output stats
status = stat(output_filename, &st_buf);
if (status != 0) {
//TODO This is not critical, but still something to be tracked
fprintf(stderr, "Failed to get output file stats. Aborting.\n");
if (status != 0) {
//TODO This is not critical, but still something to be tracked
fprintf(stderr, "Failed to get output file stats. Aborting.\n");
exit(-12);
}
o_size = st_buf.st_size;
*(o_t_size) += o_size;
}
o_size = st_buf.st_size;
*(o_t_size) += o_size;
fprintf(stdout, "%ld bytes -> %ld bytes [%.2f%%]\n",
fprintf(stdout, "%ld bytes -> %ld bytes [%.2f%%]\n",
(long) i_size, (long) o_size, ((float) o_size - i_size) * 100 / i_size);
//TODO Perform the required instructions
@ -143,7 +143,7 @@ int main (int argc, char *argv[]) {
//Parse arguments
cclt_compress_parameters pars = parse_arguments(argc, argv);
//Either -l or -q must be set but not together
if (!((pars.lossless == 1) ^ (pars.quality > 0))) {
//Both or none are set
@ -152,6 +152,7 @@ int main (int argc, char *argv[]) {
exit(-1);
} else if (pars.lossless == 0 && pars.quality <= 0) {
fprintf(stderr, "Either -l or -q must be set. Aborting.\n");
print_help();
exit(-2);
}
} else {
@ -162,19 +163,19 @@ int main (int argc, char *argv[]) {
exit(-3);
}
}
//Check if you set the input files
if (pars.input_files_count == 0) {
fprintf(stderr, "No input files. Aborting.\n");
exit(-9);
}
//Check if there's a valid scaling factor
if (pars.scaling_factor <= 0) {
fprintf(stderr, "Scaling factor must be > 0. Aborting.\n");
exit(-6);
}
//Check if the output folder exists, otherwise create it
if (pars.output_folder == NULL) {
fprintf(stderr, "No -o option pointing to the destination folder. Aborting.\n");
@ -196,6 +197,6 @@ int main (int argc, char *argv[]) {
fprintf(stdout, "-------------------------------\nCompression completed.\n%ld bytes -> %ld bytes [%.2f%%]\n",
(long) i_t_size, (long) o_t_size, ((float) o_t_size - i_t_size) * 100 / i_t_size);
exit(0);
}

121
src/png.c Normal file
View File

@ -0,0 +1,121 @@
/*
* Copyright 2002-2010 Guillaume Cottenceau.
*
* This software may be freely redistributed under the terms
* of the X11 license.
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <png.h>
#include <zlib.h>
#include <setjmp.h>
#include "png.h"
int width, height;
png_byte color_type;
png_byte bit_depth;
png_bytep *row_pointers;
void read_png_file (char *filename) {
FILE *fp = fopen(filename, "rb");
png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if(!png) abort();
png_infop info = png_create_info_struct(png);
if(!info) abort();
if(setjmp(png_jmpbuf(png))) abort();
png_init_io(png, fp);
png_read_info(png, info);
width = png_get_image_width(png, info);
height = png_get_image_height(png, info);
color_type = png_get_color_type(png, info);
bit_depth = png_get_bit_depth(png, info);
// Read any color_type into 8bit depth, RGBA format.
// See http://www.libpng.org/pub/png/libpng-manual.txt
if(bit_depth == 16)
png_set_strip_16(png);
if(color_type == PNG_COLOR_TYPE_PALETTE)
png_set_palette_to_rgb(png);
// PNG_COLOR_TYPE_GRAY_ALPHA is always 8 or 16bit depth.
if(color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
png_set_expand_gray_1_2_4_to_8(png);
if(png_get_valid(png, info, PNG_INFO_tRNS))
png_set_tRNS_to_alpha(png);
// These color_type don't have an alpha channel then fill it with 0xff.
if(color_type == PNG_COLOR_TYPE_RGB ||
color_type == PNG_COLOR_TYPE_GRAY ||
color_type == PNG_COLOR_TYPE_PALETTE)
png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
if(color_type == PNG_COLOR_TYPE_GRAY ||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
png_set_gray_to_rgb(png);
png_read_update_info(png, info);
row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * height);
for(int y = 0; y < height; y++) {
row_pointers[y] = (png_byte*)malloc(png_get_rowbytes(png,info));
}
png_read_image(png, row_pointers);
fclose(fp);
}
void write_png_file (char *filename) {
FILE *fp = fopen(filename, "wb");
if(!fp) abort();
png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png) abort();
png_infop info = png_create_info_struct(png);
if (!info) abort();
if (setjmp(png_jmpbuf(png))) abort();
png_init_io(png, fp);
// Output is 8bit depth, RGBA format.
png_set_IHDR(
png,
info,
width, height,
8,
PNG_COLOR_TYPE_RGBA,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT
);
png_write_info(png, info);
// To remove the alpha channel for PNG_COLOR_TYPE_RGB format,
// Use png_set_filler().
//png_set_filler(png, 0, PNG_FILLER_AFTER);
png_write_image(png, row_pointers);
png_write_end(png, NULL);
for(int y = 0; y < height; y++) {
free(row_pointers[y]);
}
free(row_pointers);
fclose(fp);
}

9
src/png.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef CCLT_PNG
#define CCLT_PNG
#include <png.h>
void read_png_file (char *filename);
void write_png_file (char *filename);
#endif

View File

@ -6,8 +6,6 @@
#include <errno.h>
#include <setjmp.h>
#include <stdio.h>
#include <jpeglib.h>
#include <turbojpeg.h>
#include <string.h>
#include <getopt.h>
#include <ctype.h>
@ -19,26 +17,7 @@
#include "utils.h"
#include "compress.h"
#include "lossless.h"
cclt_compress_parameters initialize_compression_parameters() {
cclt_compress_parameters par;
par.quality = 0;
par.width = 0;
par.height = 0;
par.scaling_factor = 100;
par.color_space = TJPF_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;
return par;
}
int string_to_int(char* in_string) {
long value = 0;
@ -64,7 +43,7 @@ int string_to_int(char* in_string) {
void print_help() {
fprintf(stdout,
"CCLT - Caesium Command Line Tools\n\n"
"Usage: cclt [OPTION] INPUT...\n"
"Usage: caesiumclt [OPTIONs] INPUT...\n"
"Compress your pictures up to 90%% without visible quality loss.\n\n"
"Options:\n"
@ -73,7 +52,8 @@ void print_help() {
"\t-o\tcompress to custom folder\n"
"\t-l\tuse lossless optimization\n"
"\t-s\tscale to value, expressed as percentage (e.g. 20%%)\n"
"\t-R\tif input is a folder, scan subfolders too\n"
//TODO Remove this warning
"\t-R\tif input is a folder, scan subfolders too [NOT IMPLEMENTED YET]\n"
"\t-h\tdisplay this help and exit\n"
"\t-v\toutput version information and exit\n\n");
exit(0);
@ -112,87 +92,6 @@ int mkpath(const char *pathname, mode_t mode) {
return -1;
}
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;
case 'R':
parameters.recursive = 1;
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;
}
void cclt_compress_routine(char* input, char* output, cclt_compress_parameters* pars) {
enum image_type type = detect_image_type(input);
if (type == JPEG) {
cclt_compress(output, cclt_decompress(input, pars), pars);
cclt_optimize(output, output, pars->exif_copy, input);
} else if (type == PNG) {
printf("PNG detected. Still to implement.\n");
} else {
return;
}
}
char** scan_folder(char* dir, int depth) {
int i = 0;
DIR *dp;

View File

@ -27,18 +27,14 @@ typedef struct cclt_compress_parameters {
enum image_type {
JPEG,
PNG,
GIF,
UNKN,
};
cclt_compress_parameters initialize_compression_parameters();
int string_to_int(char* in_string);
void print_help();
void print_progress(int current, int max, char* message);
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[]);
void cclt_compress_routine(char* input, char* output,cclt_compress_parameters* pars);
enum image_type detect_image_type(char* path);
#endif