Enabled PNG support using zopfli

Not tested yet on Linux systems.
This commit is contained in:
Matteo Paonessa 2015-09-11 23:52:04 +02:00
parent ccba6a5a44
commit 0528b5c905
13 changed files with 8096 additions and 25 deletions

2
.gitignore vendored
View File

@ -3,5 +3,3 @@ samples/*
tmp/*
build/*
autom4te.cache
src/png.c
src/png.h

15
INSTALL
View File

@ -8,6 +8,13 @@ are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. This file is offered as-is,
without warranty of any kind.
Requirements
==================
You will need both mozjpeg and zopflipng compiled as libraries to be able to
compile CaesiumCLT. Refer to their own documentation for the detailed
instructions.
Basic Installation
==================
@ -26,6 +33,14 @@ Cloning from git
==================
$ git clone https://github.com/Lymphatus/CaesiumCLT
$ cd CaesiumCLT
$ (optional) autoreconf -fiv
$ ./configure
$ make
$ sudo make install
You can build out of the source tree in a separate folder. For example:
$ mkdir build
$ cd build
$ ../configure
$ make
$ sudo make install

View File

@ -1,17 +1,17 @@
## Caesium Command Line Tools
##### CCLT - v 1.9.9 BETA (build 20150728) - Copyright © Matteo Paonessa, 2015. All Rights Reserved.
##### CCLT - v 1.9.9 BETA (build 20150911) - Copyright © Matteo Paonessa, 2015. All Rights Reserved.
----------
###### REQUIREMENTS
* [libjpeg-turbo](http://libjpeg-turbo.org/)
* [libpng](http://libpng.org/)
* [zlib](http://www.zlib.net/)
* [mozjpeg](https://github.com/mozilla/mozjpeg)
* [zopfli](https://github.com/google/zopfli)
* [lodepng](https://github.com/lvandeve/lodepng)
----------
###### TESTED PLATFORMS
* MacOSX Yosemite (v. 10.10.4)
* MacOSX Yosemite (v. 10.10.5)
* Arch Linux
* Ubuntu 14.04.2
@ -24,6 +24,8 @@ See INSTALL for more details.
###### TODO
* Recursive folder support
* GIF support?
* Code cleaning
----------

View File

@ -1,4 +1,4 @@
bin_PROGRAMS = caesiumclt
caesiumclt_SOURCES = main.c jpeg.c compresshelper.c utils.c
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 = -ljpeg -lturbojpeg -lm
caesiumclt_LDADD = -ljpeg -lturbojpeg -lm -lzopflipng

View File

@ -100,7 +100,8 @@ am__installdirs = "$(DESTDIR)$(bindir)"
PROGRAMS = $(bin_PROGRAMS)
am_caesiumclt_OBJECTS = caesiumclt-main.$(OBJEXT) \
caesiumclt-jpeg.$(OBJEXT) caesiumclt-compresshelper.$(OBJEXT) \
caesiumclt-utils.$(OBJEXT)
caesiumclt-utils.$(OBJEXT) caesiumclt-png.$(OBJEXT) \
caesiumclt-lodepng.$(OBJEXT)
caesiumclt_OBJECTS = $(am_caesiumclt_OBJECTS)
caesiumclt_DEPENDENCIES =
caesiumclt_LINK = $(CCLD) $(caesiumclt_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
@ -252,9 +253,9 @@ target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
caesiumclt_SOURCES = main.c jpeg.c compresshelper.c utils.c
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 = -ljpeg -lturbojpeg -lm
caesiumclt_LDADD = -ljpeg -lturbojpeg -lm -lzopflipng
all: all-am
.SUFFIXES:
@ -343,7 +344,9 @@ distclean-compile:
@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-lodepng.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:
@ -416,6 +419,34 @@ 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-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-png.o `test -f 'png.c' || echo '$(srcdir)/'`png.c
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-png.obj `if test -f 'png.c'; then $(CYGPATH_W) 'png.c'; else $(CYGPATH_W) '$(srcdir)/png.c'; fi`
caesiumclt-lodepng.o: lodepng.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(caesiumclt_CFLAGS) $(CFLAGS) -MT caesiumclt-lodepng.o -MD -MP -MF $(DEPDIR)/caesiumclt-lodepng.Tpo -c -o caesiumclt-lodepng.o `test -f 'lodepng.c' || echo '$(srcdir)/'`lodepng.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/caesiumclt-lodepng.Tpo $(DEPDIR)/caesiumclt-lodepng.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lodepng.c' object='caesiumclt-lodepng.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-lodepng.o `test -f 'lodepng.c' || echo '$(srcdir)/'`lodepng.c
caesiumclt-lodepng.obj: lodepng.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(caesiumclt_CFLAGS) $(CFLAGS) -MT caesiumclt-lodepng.obj -MD -MP -MF $(DEPDIR)/caesiumclt-lodepng.Tpo -c -o caesiumclt-lodepng.obj `if test -f 'lodepng.c'; then $(CYGPATH_W) 'lodepng.c'; else $(CYGPATH_W) '$(srcdir)/lodepng.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/caesiumclt-lodepng.Tpo $(DEPDIR)/caesiumclt-lodepng.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lodepng.c' object='caesiumclt-lodepng.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-lodepng.obj `if test -f 'lodepng.c'; then $(CYGPATH_W) 'lodepng.c'; else $(CYGPATH_W) '$(srcdir)/lodepng.c'; fi`
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am

View File

@ -104,13 +104,12 @@ cclt_compress_parameters parse_arguments(int argc, char* argv[]) {
void cclt_compress_routine(char* input, char* output, cclt_compress_parameters* pars) {
enum image_type type = detect_image_type(input);
if (type == JPEG && pars->lossless == 0) {
cclt_compress(output, cclt_decompress(input, pars), pars);
cclt_optimize(output, output, pars->exif_copy, input);
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_optimize(input, output, pars->exif_copy, input);
cclt_jpeg_optimize(input, output, pars->exif_copy, input);
} else if (type == PNG) {
//read_png_file(input);
//write_png_file(output);
cclt_png_optimize(input, output);
} else if (type == GIF) {
printf("GIF detected. Not implemented yet.\n");
} else {

View File

@ -45,7 +45,7 @@ struct jpeg_decompress_struct cclt_get_markers(char* input) {
return einfo;
}
int cclt_optimize(char* input_file, char* output_file, int exif_flag, char* exif_src) {
int cclt_jpeg_optimize(char* input_file, char* output_file, int exif_flag, char* exif_src) {
//File pointer for both input and output
FILE* fp;
@ -146,7 +146,7 @@ int cclt_optimize(char* input_file, char* output_file, int exif_flag, char* exif
return 0;
}
void cclt_compress(char* output_file, unsigned char* image_buffer, cclt_compress_parameters* pars) {
void cclt_jpeg_compress(char* output_file, unsigned char* image_buffer, cclt_compress_parameters* pars) {
FILE* fp;
tjhandle tjCompressHandle;
unsigned char* output_buffer;
@ -187,7 +187,7 @@ void cclt_compress(char* output_file, unsigned char* image_buffer, cclt_compress
}
unsigned char* cclt_decompress(char* fileName, cclt_compress_parameters* pars) {
unsigned char* cclt_jpeg_decompress(char* fileName, cclt_compress_parameters* pars) {
//TODO I/O Error handling

View File

@ -5,10 +5,10 @@
#include "utils.h"
int cclt_optimize(char* input_file, char* output_file, int exif_flag, char* exif_src);
int cclt_jpeg_optimize(char* input_file, char* output_file, int exif_flag, char* exif_src);
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 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 jcopy_markers_execute (j_decompress_ptr srcinfo, j_compress_ptr dstinfo);

6252
src/lodepng.c Normal file

File diff suppressed because it is too large Load Diff

1716
src/lodepng.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -106,7 +106,7 @@ void cclt_start(char** input_files, int n, char* output_folder, cclt_compress_pa
fprintf(stdout, "Compressing: %s -> %s\n", input_files[i], output_filename);
//if (lossless != 0) {
// cclt_optimize(input_files[i], output_filename, exif, input_files[i]);
// cclt_jpeg_optimize(input_files[i], output_filename, exif, input_files[i]);
//} else {
cclt_compress_routine(input_files[i], output_filename, pars);
//}

52
src/png.c Normal file
View File

@ -0,0 +1,52 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "lodepng.h"
#include "zopflipng/zopflipng_lib.h"
#include "png.h"
void cclt_png_optimize(char* input, char* output) {
//TODO Error handling
CZopfliPNGOptions png_options;
CZopfliPNGSetDefaults(&png_options);
unsigned char* orig_buffer;
size_t orig_buffer_size;
unsigned char* resultpng;
size_t resultpng_size;
png_options.num_iterations = 15;
png_options.num_iterations_large = 15;
png_options.block_split_strategy = 3;
png_options.lossy_8bit = 1;
png_options.lossy_transparent = 1;
png_options.auto_filter_strategy = 1;
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 (lodepng_save_file(resultpng, resultpng_size, output) != 0) {
fprintf(stderr, "Error while writing PNG. Aborting.\n");
exit(-18);
}
free(orig_buffer);
free(resultpng);
}

6
src/png.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef CCLT_PNG
#define CCLT_PNG
void cclt_png_optimize(char* input, char* output);
#endif