Commit c5011ce4 authored by Mathieu Malaterre's avatar Mathieu Malaterre

Import Upstream version 1.4.3

parent c3dd5a24
jpegoptim
=========
Copyright (C) 1996-2013 Timo Kokkonen <tjko@iki.fi>
Copyright (C) 1996-2015 Timo Kokkonen <tjko@iki.fi>
This program is free software; you can redistribute it
......
......@@ -3,7 +3,7 @@
#
# Makefile for jpegoptim
#
Version = 1.4.1
Version = 1.4.3
PKGNAME = jpegoptim
SHELL = /bin/sh
......@@ -15,24 +15,27 @@ VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
datarootdir = @datarootdir@
datadir = @datadir@
# Where to install the executables.
bindir = $(exec_prefix)/bin
bindir = @bindir@
# Where to put libraries
libdir = $(prefix)/lib
libdir = @libdir@
# Where to put the Info files
infodir = $(prefix)/share/info
infodir = @infodir@
# Where to put the manual pages.
mandir = $(prefix)/share/man
mandir = @mandir@
CC = @CC@
XCPPFLAGS = @CPPFLAGS@
CFLAGS = @CFLAGS@ $(XCPPFLAGS) $(DEFS)
#CFLAGS += -Wall -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
STRIP = strip
......@@ -52,10 +55,14 @@ DISTNAME = $(PKGNAME)-$(Version)
OBJS = $(PKGNAME).o jpegdest.o misc.o @GNUGETOPT@
all: $(PKGNAME)
dssim.o: dssim.c
$(CC) $(CFLAGS) -std=c99 -c
$(PKGNAME): $(OBJS)
$(CC) $(CFLAGS) -o $(PKGNAME) $(OBJS) $(LDFLAGS) $(LIBS)
all: $(PKGNAME)
strip:
for i in $(PKGNAME) ; do [ -x $$i ] && $(STRIP) $$i ; done
......@@ -77,18 +84,18 @@ archive:
install: all install.dirs install.man
$(INSTALL) -m 755 $(PKGNAME) $(DESTDIR)/$(bindir)/$(PKGNAME)
$(INSTALL) -m 755 $(PKGNAME) $(DESTDIR)$(bindir)/$(PKGNAME)
printable.man:
groff -Tps -mandoc ./$(PKGNAME).1 >$(PKGNAME).ps
groff -Tascii -mandoc ./$(PKGNAME).1 | tee $(PKGNAME).prn | sed 's/.//g' >$(PKGNAME).txt
install.man: install.dirs
$(INSTALL) -m 644 $(PKGNAME).1 $(DESTDIR)/$(mandir)/man1/$(PKGNAME).1
$(INSTALL) -m 644 $(PKGNAME).1 $(DESTDIR)$(mandir)/man1/$(PKGNAME).1
install.dirs:
$(INSTALL) -d -m 755 $(DESTDIR)/$(mandir)/man1
$(INSTALL) -d -m 755 $(DESTDIR)/$(bindir)
$(INSTALL) -d -m 755 $(DESTDIR)$(mandir)/man1
$(INSTALL) -d -m 755 $(DESTDIR)$(bindir)
# a tradition !
love:
......
Jpegoptim v1.4.1 - Copyright (c) Timo Kokkonen, 1996-2014. All Rights Reserved.
Jpegoptim v1.4.3 - Copyright (c) Timo Kokkonen, 1996-2015. All Rights Reserved.
REQUIREMENTS
......@@ -10,7 +10,7 @@ TESTED PLATFORMS
Linux
Solaris
Darwin/OS X j
Windows (should now compile with minimal effort...)
Windows (setargv.obj "link option" may be needed for wildcards expansion to work)
INSTALLATION
......@@ -18,8 +18,8 @@ INSTALLATION
tar file, make necessary changes to the Makefile, and then
compile the program. You may wanna do something like this:
zcat jpegoptim-1.4.1.tar.gz | tar xf -
cd jpegoptim-1.4.1
zcat jpegoptim-1.4.3.tar.gz | tar xf -
cd jpegoptim-1.4.3
./configure
make
make strip
......@@ -27,6 +27,10 @@ INSTALLATION
HISTORY
v1.4.3 - fix bug that could cause jpegoptim crash when processing
certain jpeg files
v1.4.2 - add option -P, --preserve-perms,
some minor fixes
v1.4.1 - fix --stdin option (assume -f when reading from stdin),
workaround to bug in libjpeg-turboi (v1.3.1) triggered
when option -V or --version was used,
......@@ -84,5 +88,5 @@ LATEST VERSION
Timo <tjko@iki.fi>
27-May-2014 $Id$
18-May-2015 $Id$
......@@ -3375,9 +3375,9 @@ exit 1
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for round in -lm" >&5
$as_echo_n "checking for round in -lm... " >&6; }
if ${ac_cv_lib_m_round+:} false; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for floor in -lm" >&5
$as_echo_n "checking for floor in -lm... " >&6; }
if ${ac_cv_lib_m_floor+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
......@@ -3391,27 +3391,27 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
#ifdef __cplusplus
extern "C"
#endif
char round ();
char floor ();
int
main ()
{
return round ();
return floor ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_m_round=yes
ac_cv_lib_m_floor=yes
else
ac_cv_lib_m_round=no
ac_cv_lib_m_floor=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_round" >&5
$as_echo "$ac_cv_lib_m_round" >&6; }
if test "x$ac_cv_lib_m_round" = xyes; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_floor" >&5
$as_echo "$ac_cv_lib_m_floor" >&6; }
if test "x$ac_cv_lib_m_floor" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_LIBM 1
_ACEOF
......
......@@ -36,7 +36,8 @@ echo "Cannot find libjpeg or you have too old version (v6 or later required)."
exit 1
])
AC_CHECK_LIB(m, round)
dnl AC_CHECK_LIB(m, round)
AC_CHECK_LIB(m, floor)
dnl Checks for header files.
......
.TH JPEGOPTIM 1 "27 May 2014"
.TH JPEGOPTIM 1 "28 Nov 2014"
.UC 4
.SH NAME
jpegoptim \- utility to optimize/compress JPEG/JFIF files.
......@@ -83,6 +83,15 @@ Overwrite target file even if it exists (when using -d option).
.B -p, --preserve
Preserve file modification times.
.TP 0.6i
.B -P, --preserve-perms
Preserve file permissions (owner/group) by overwriting the original file. This is
slightly less safe than the default mode of operation (where new file is first saved
as temporary file and then renamed over the original file).
In this mode a backup of the original file is made with .jpegoptim.bak extension,
and this file is removed after the original file has been successfully replaced.
NOTE! if running jpegoptim as root there is generally no need to use this option,
as jpegoptim is able to preserve file permissions when run by root in default mode.
.TP 0.6i
.B -q, --quiet
Quiet mode.
.TP 0.6i
......@@ -99,7 +108,7 @@ all input files to progressive JPEGs when used with --force option.
.TP 0.6i
.B --all-progressive
Force all output files to be progressive. Can be used to convert
all input files to normal (non-progressive) JPEGs when used with --force option.
all normal (non-progressive) JPEGs input files to progressive when used with --force option.
.TP 0.6i
.B -s, --strip-all
......@@ -161,7 +170,7 @@ jpeginfo(1)
Timo Kokkonen <tjko@iki.fi>
.SH COPYING
Copyright (C) 1996-2014 Timo Kokkonen
Copyright (C) 1996-2015 Timo Kokkonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......
/*******************************************************************
* JPEGoptim
* Copyright (c) Timo Kokkonen, 1996-2014.
* Copyright (c) Timo Kokkonen, 1996-2015.
* All Rights Reserved.
*
* requires libjpeg (Independent JPEG Group's JPEG software
......@@ -34,7 +34,9 @@
#include "jpegoptim.h"
#define VERSIO "1.4.1"
#define VERSIO "1.4.3"
#define COPYRIGHT "Copyright (c) 1996-2015, Timo Kokkonen"
#define LOG_FH (logs_to_stdout ? stdout : stderr)
......@@ -61,6 +63,7 @@ int verbose_mode = 0;
int quiet_mode = 0;
int global_error_counter = 0;
int preserve_mode = 0;
int preserve_perms = 0;
int overwrite_mode = 0;
int totals_mode = 0;
int stdin_mode = 0;
......@@ -95,6 +98,7 @@ struct option long_options[] = {
{"force",0,0,'f'},
{"version",0,0,'V'},
{"preserve",0,0,'p'},
{"preserve-perms",0,0,'P'},
{"strip-all",0,0,'s'},
{"strip-none",0,&strip_none,1},
{"strip-com",0,&save_com,0},
......@@ -143,8 +147,7 @@ my_output_message (j_common_ptr cinfo)
void print_usage(void)
{
fprintf(stderr,PROGRAMNAME " v" VERSIO
" Copyright (c) Timo Kokkonen, 1996-2014.\n");
fprintf(stderr,PROGRAMNAME " v" VERSIO " " COPYRIGHT "\n");
fprintf(stderr,
"Usage: " PROGRAMNAME " [options] <filenames> \n\n"
......@@ -165,8 +168,11 @@ void print_usage(void)
" -T<threshold>, --threshold=<threshold>\n"
" keep old file if the gain is below a threshold (%%)\n"
" -b, --csv print progress info in CSV format\n"
" -o, --overwrite overwrite target file even if it exists\n"
" -o, --overwrite overwrite target file even if it exists (meaningful\n"
" only when used with -d, --dest option)\n"
" -p, --preserve preserve file timestamps\n"
" -P, --preserve-perms\n"
" preserve original file permissions by overwriting it\n"
" -q, --quiet quiet mode\n"
" -t, --totals print totals after processing all files\n"
" -v, --verbose enable verbose mode (positively chatty)\n"
......@@ -192,7 +198,7 @@ void print_version()
printf(PROGRAMNAME " v%s %s\n",VERSIO,HOST_TYPE);
printf("Copyright (c) 1996-2014 Timo Kokkonen.\n");
printf(COPYRIGHT "\n");
if (!(err=jpeg_std_error(&jcerr)))
fatal("jpeg_std_error() failed");
......@@ -344,7 +350,7 @@ int main(int argc, char **argv)
/* parse command line parameters */
while(1) {
opt_index=0;
if ((c=getopt_long(argc,argv,"d:hm:nstqvfVpoT:S:b",long_options,&opt_index))
if ((c=getopt_long(argc,argv,"d:hm:nstqvfVpPoT:S:b",long_options,&opt_index))
== -1)
break;
......@@ -407,6 +413,9 @@ int main(int argc, char **argv)
case 'p':
preserve_mode=1;
break;
case 'P':
preserve_perms=1;
break;
case 's':
save_exif=0;
save_iptc=0;
......@@ -480,6 +489,7 @@ int main(int argc, char **argv)
do {
if (stdin_mode) {
infile=stdin;
set_filemode_binary(infile);
} else {
if (!argv[i][0]) continue;
if (argv[i][0]=='-') continue;
......@@ -512,7 +522,7 @@ int main(int argc, char **argv)
warn("skipping special file: %s",argv[i]);
continue;
}
if ((infile=fopen(argv[i],"r"))==NULL) {
if ((infile=fopen(argv[i],"rb"))==NULL) {
warn("cannot open file: %s", argv[i]);
continue;
}
......@@ -556,7 +566,7 @@ int main(int argc, char **argv)
if (cmarker->marker == EXIF_JPEG_MARKER &&
!memcmp(cmarker->data,EXIF_IDENT_STRING,EXIF_IDENT_STRING_SIZE))
strncat(marker_str,"Exiff ",sizeof(marker_str)-strlen(marker_str)-1);
strncat(marker_str,"Exif ",sizeof(marker_str)-strlen(marker_str)-1);
if (cmarker->marker == IPTC_JPEG_MARKER)
strncat(marker_str,"IPTC ",sizeof(marker_str)-strlen(marker_str)-1);
......@@ -619,14 +629,13 @@ int main(int argc, char **argv)
fflush(LOG_FH);
}
fclose(infile);
infile=NULL;
if (dest && !noaction) {
if (file_exists(newname) && !overwrite_mode) {
warn("target file already exists: %s\n",newname);
jpeg_abort_decompress(&dinfo);
fclose(infile);
if (buf) FREE_LINE_BUF(buf,dinfo.output_height);
continue;
}
......@@ -638,6 +647,7 @@ int main(int argc, char **argv)
jpeg_abort_compress(&cinfo);
jpeg_abort_decompress(&dinfo);
fclose(infile);
if (!quiet_mode) fprintf(LOG_FH," [Compress ERROR]\n");
if (buf) FREE_LINE_BUF(buf,dinfo.output_height);
compress_err_count++;
......@@ -735,7 +745,7 @@ int main(int argc, char **argv)
} else {
int newquality;
int dif = round(abs(oldquality-quality)/2.0);
int dif = floor((abs(oldquality-quality)/2.0)+0.5);
if (osize > tsize) {
newquality=quality-dif;
if (dif < 1) { newquality--; searchdone=1; }
......@@ -758,6 +768,7 @@ int main(int argc, char **argv)
if (buf) FREE_LINE_BUF(buf,dinfo.output_height);
jpeg_finish_decompress(&dinfo);
fclose(infile);
if (quality>=0 && outsize>=insize && !retry && !stdin_mode) {
......@@ -780,46 +791,50 @@ int main(int argc, char **argv)
if (stdout_mode) {
outfname=NULL;
set_filemode_binary(stdout);
if (fwrite(outbuffer,outbuffersize,1,stdout) != 1)
fatal("write failed to stdout");
} else {
if (preserve_perms && !dest) {
/* make backup of the original file */
snprintf(tmpfilename,sizeof(tmpfilename),"%s.jpegoptim.bak",newname);
if (verbose_mode > 1 && !quiet_mode)
fprintf(LOG_FH,"creating backup of original image as: %s\n",tmpfilename);
if (file_exists(tmpfilename))
fatal("backup file already exists: %s",tmpfilename);
if (copy_file(newname,tmpfilename))
fatal("failed to create backup of original file");
if ((outfile=fopen(newname,"wb"))==NULL)
fatal("error opening output file: %s", newname);
outfname=newname;
} else {
#ifdef HAVE_MKSTEMPS
/* rely on mkstemps() to create us temporary file safely... */
snprintf(tmpfilename,sizeof(tmpfilename),
"%sjpegoptim-%d-%d.XXXXXX.tmp", tmpdir, (int)getuid(), (int)getpid());
if ((tmpfd = mkstemps(tmpfilename,4)) < 0)
fatal("error creating temp file: mkstemps() failed");
if ((outfile=fdopen(tmpfd,"w"))==NULL)
/* rely on mkstemps() to create us temporary file safely... */
snprintf(tmpfilename,sizeof(tmpfilename),
"%sjpegoptim-%d-%d.XXXXXX.tmp", tmpdir, (int)getuid(), (int)getpid());
if ((tmpfd = mkstemps(tmpfilename,4)) < 0)
fatal("error creating temp file: mkstemps() failed");
if ((outfile=fdopen(tmpfd,"wb"))==NULL)
#else
/* if platform is missing mkstemps(), try to create at least somewhat "safe" temp file... */
snprintf(tmpfilename,sizeof(tmpfilename),
"%sjpegoptim-%d-%d.%d.tmp", tmpdir, (int)getuid(), (int)getpid(),time(NULL));
tmpfd=0;
if ((outfile=fopen(tmpfilename,"w"))==NULL)
/* if platform is missing mkstemps(), try to create at least somewhat "safe" temp file... */
snprintf(tmpfilename,sizeof(tmpfilename),
"%sjpegoptim-%d-%d.%d.tmp", tmpdir, (int)getuid(), (int)getpid(),time(NULL));
tmpfd=0;
if ((outfile=fopen(tmpfilename,"wb"))==NULL)
#endif
fatal("error opening temporary file: %s",tmpfilename);
outfname=tmpfilename;
fatal("error opening temporary file: %s",tmpfilename);
outfname=tmpfilename;
}
if (verbose_mode > 1 && !quiet_mode)
fprintf(LOG_FH,"writing %lu bytes to temporary file: %s\n",
fprintf(LOG_FH,"writing %lu bytes to file: %s\n",
(long unsigned int)outbuffersize, outfname);
if (fwrite(outbuffer,outbuffersize,1,outfile) != 1)
fatal("write failed to temporary file");
fatal("write failed to file: %s", outfname);
fclose(outfile);
}
if (outfname) {
/* preserve file mode */
if (chmod(outfname,(file_stat.st_mode & 0777)) != 0)
warn("failed to set output file mode");
/* preserve file group (and owner if run by root) */
if (chown(outfname,
(geteuid()==0 ? file_stat.st_uid : -1),
file_stat.st_gid) != 0)
warn("failed to reset output file group/owner");
if (preserve_mode) {
/* preserve file modification time */
......@@ -830,9 +845,27 @@ int main(int argc, char **argv)
warn("failed to reset output file time/date");
}
if (verbose_mode > 1 && !quiet_mode)
fprintf(LOG_FH,"renaming: %s to %s\n",outfname,newname);
if (rename_file(outfname,newname)) fatal("cannot rename temp file");
if (preserve_perms && !dest) {
/* original file was already replaced, remove backup... */
if (delete_file(tmpfilename))
warn("failed to remove backup file: %s",tmpfilename);
} else {
/* make temp file to be the original file... */
/* preserve file mode */
if (chmod(outfname,(file_stat.st_mode & 0777)) != 0)
warn("failed to set output file mode");
/* preserve file group (and owner if run by root) */
if (chown(outfname,
(geteuid()==0 ? file_stat.st_uid : -1),
file_stat.st_gid) != 0)
warn("failed to reset output file group/owner");
if (verbose_mode > 1 && !quiet_mode)
fprintf(LOG_FH,"renaming: %s to %s\n",outfname,newname);
if (rename_file(outfname,newname)) fatal("cannot rename temp file");
}
}
} else {
if (!quiet_mode || csv) fprintf(LOG_FH,csv ? "skipped\n" : "skipped.\n");
......
......@@ -20,6 +20,7 @@ extern "C" {
#include <utime.h>
#define DIR_SEPARATOR_C '/'
#define DIR_SEPARATOR_S "/"
#define set_filemode_binary(file) {}
#endif
#include <sys/types.h>
#include <sys/stat.h>
......@@ -62,6 +63,7 @@ int is_directory(const char *path);
int is_file(const char *filename, struct stat *st);
int file_exists(const char *pathname);
int rename_file(const char *old_path, const char *new_path);
int copy_file(const char *srcname, const char *dstname);
char *splitdir(const char *pathname, char *buf, int buflen);
char *splitname(const char *pathname, char *buf, int buflen);
void fatal(const char *format, ...);
......
......@@ -29,7 +29,7 @@ int delete_file(char *name)
if (!name) return -1;
if (verbose_mode > 1 && !quiet_mode) fprintf(stderr,"deleting: %s\n",name);
if ((retval=unlink(name)) && !quiet_mode)
fprintf(stderr,PROGRAMNAME ": error removing file: %s\n",name);
warn("error removing file: %s",name);
return retval;
}
......@@ -88,6 +88,54 @@ int rename_file(const char *old_path, const char *new_path)
}
#define COPY_BUF_SIZE (256*1024)
int copy_file(const char *srcfile, const char *dstfile)
{
FILE *in,*out;
unsigned char buf[COPY_BUF_SIZE];
int r,w;
int err=0;
if (!srcfile || !dstfile) return -1;
in=fopen(srcfile,"rb");
if (!in) {
warn("failed to open file for reading: %s", srcfile);
return -2;
}
out=fopen(dstfile,"wb");
if (!out) {
fclose(in);
warn("failed to open file for writing: %s", dstfile);
return -3;
}
do {
r=fread(buf,1,sizeof(buf),in);
if (r > 0) {
w=fwrite(buf,1,r,out);
if (w != r) {
err=1;
warn("error writing to file: %s", dstfile);
break;
}
} else {
if (ferror(in)) {
err=2;
warn("error reading file: %s", srcfile);
break;
}
}
} while (!feof(in));
fclose(out);
fclose(in);
return err;
}
char *splitdir(const char *pathname, char *buf, int buflen)
{
char *s = NULL;
......
Summary: Utility for optimizing/compressing JPEG files.
Name: jpegoptim
Version: 1.4.1
Version: 1.4.3
Release: 1
License: GPL
Group: Applications/Multimedia
......
/* win32_compat.h
*
* compatibility stuff for Windows
*
* Thanks to Javier Gutiérrez Chamorro for Windows support.
*/
#ifndef _WIN32_COMPAT_H
......@@ -23,6 +25,8 @@ extern "C" {
#define realpath(N,R) _fullpath((R),(N),MAXPATHLEN)
#define ftruncate(fildes,length) open(fildes, O_TRUNC|O_WRONLY)
#define set_filemode_binary(file) _setmode(_fileno(file), _O_BINARY)
#define round(x) ((int) (x))
#define getuid(x) 0
#define geteuid() 0
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment