Skip to content

Commit

Permalink
Implement in-memory source/destination managers even when not emulati…
Browse files Browse the repository at this point in the history
…ng the libjpeg v8 API/ABI

git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@913 632fc199-4ca6-4c93-a231-07263d6284db
  • Loading branch information
dcommander committed Jan 18, 2013
1 parent b87136c commit ab70623
Show file tree
Hide file tree
Showing 18 changed files with 438 additions and 52 deletions.
17 changes: 15 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ option(WITH_ARITH_ENC "Include arithmetic encoding support" TRUE)
option(WITH_ARITH_DEC "Include arithmetic decoding support" TRUE)
option(WITH_JPEG7 "Emulate libjpeg v7 API/ABI (this makes libjpeg-turbo backward incompatible with libjpeg v6b)" FALSE)
option(WITH_JPEG8 "Emulate libjpeg v8 API/ABI (this makes libjpeg-turbo backward incompatible with libjpeg v6b)" FALSE)
option(WITH_MEM_SRCDST "Include in-memory source/destination manager functions when emulating the libjpeg v6b or v7 API/ABI" TRUE)
option(WITH_JAVA "Build Java wrapper for the TurboJPEG/OSS library" FALSE)

if(WITH_ARITH_ENC)
Expand All @@ -67,9 +68,14 @@ else()
message(STATUS "TurboJPEG/OSS Java wrapper disabled")
endif()

set(SO_AGE 0)
if(WITH_MEM_SRCDST)
set(SO_AGE 1)
endif()

set(JPEG_LIB_VERSION 62)
set(DLL_VERSION ${JPEG_LIB_VERSION})
set(FULLVERSION ${DLL_VERSION}.0.0)
set(FULLVERSION ${DLL_VERSION}.${SO_AGE}.0)
if(WITH_JPEG8)
set(JPEG_LIB_VERSION 80)
set(DLL_VERSION 8)
Expand All @@ -78,10 +84,17 @@ if(WITH_JPEG8)
elseif(WITH_JPEG7)
set(JPEG_LIB_VERSION 70)
set(DLL_VERSION 7)
set(FULLVERSION ${DLL_VERSION}.0.0)
set(FULLVERSION ${DLL_VERSION}.${SO_AGE}.0)
message(STATUS "Emulating libjpeg v7 API/ABI")
endif(WITH_JPEG8)

if(WITH_MEM_SRCDST)
set(MEM_SRCDST_SUPPORTED 1)
message(STATUS "In-memory source/destination managers enabled")
else()
message(STATUS "In-memory source/destination managers disabled")
endif()

if(MSVC)
# Use the static C library for all build types
foreach(var CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
Expand Down
10 changes: 10 additions & 0 deletions ChangeLog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,16 @@ images (feature ported from jpeg-8d.)
multiple "Mismatch in operand sizes" errors when attempting to build the x86
SIMD code with NASM 0.98.

[12] The in-memory source/destination managers (jpeg_mem_src() and
jpeg_mem_dest()) are now included by default when building libjpeg-turbo with
libjpeg v6b or v7 emulation, so that programs can take advantage of these
functions without requiring the use of the backward-incompatible libjpeg v8
ABI. The "age number" of the libjpeg-turbo library on Un*x systems has been
incremented by 1 to reflect this. You can disable this feature with a
configure/CMake switch in order to retain strict API/ABI compatibility with the
libjpeg v6b or v7 API/ABI (or with previous versions of libjpeg-turbo.) See
README-turbo.txt for more details.


1.2.1
=====
Expand Down
2 changes: 1 addition & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
lib_LTLIBRARIES = libjpeg.la
libjpeg_la_LDFLAGS = -version-info ${SO_MAJOR_VERSION}:${SO_MINOR_VERSION} -no-undefined
libjpeg_la_LDFLAGS = -version-info ${SO_MAJOR_VERSION}:${SO_MINOR_VERSION}:${SO_AGE} -no-undefined
include_HEADERS = jerror.h jmorecfg.h jpeglib.h

if WITH_TURBOJPEG
Expand Down
42 changes: 37 additions & 5 deletions README-turbo.txt
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,9 @@ Fully supported:

-- libjpeg: arithmetic coding

-- libjpeg: In-memory source and destination managers
See notes below.

-- cjpeg: Separate quality settings for luminance and chrominance
Note that the libpjeg v7+ API was extended to accommodate this feature only
for convenience purposes. It has always been possible to implement this
Expand All @@ -306,11 +309,6 @@ Fully supported:
-- rdjpgcom: locale awareness


Fully supported when using libjpeg v7/v8 emulation:

-- libjpeg: In-memory source and destination managers


Not supported:

NOTE: As of this writing, extensive research has been conducted into the
Expand Down Expand Up @@ -369,6 +367,40 @@ there is not sufficient technical justification for software to upgrade from
libjpeg v8 to libjpeg v9, and therefore, not sufficient technical justification
for us to emulate the libjpeg v9 ABI.

=====================================
In-Memory Source/Destination Managers
=====================================

By default, libjpeg-turbo 1.3 and later includes the jpeg_mem_src() and
jpeg_mem_dest() functions, even when not emulating the libjpeg v8 API/ABI.
Previously, it was necessary to build libjpeg-turbo from source with libjpeg v8
API/ABI emulation in order to use the in-memory source/destination managers,
but several projects requested that those functions be included when emulating
the libjpeg v6b API/ABI as well. This allows the use of those functions
without breaking backward ABI compatibility with libjpeg v6b, and it allows
those functions to be provided in the "official" libjpeg-turbo binaries.

Those who are concerned about maintaining strict conformance with the libjpeg
v6b or v7 API can pass an argument of --without-mem-srcdst to configure or
an argument of -DWITH_MEM_SRCDST=0 to CMake prior to building libjpeg-turbo.
This will restore the pre-1.3 behavior, in which jpeg_mem_src() and
jpeg_mem_dest() are only included when emulating the libjpeg v8 API/ABI.

On Un*x systems, including the in-memory source/destination managers changes
the dynamic library version from 62.0.0 to 62.1.0 if using libjpeg v6b API/ABI
emulation and from 7.0.0 to 7.1.0 if using libjpeg v7 API/ABI emulation.

Note that, on most operating systems, the dynamic linker will not look for
a function in a library until that function is actually used. Thus, if a
program is built against libjpeg-turbo 1.3+ and uses jpeg_mem_src() or
jpeg_mem_dest(), that program will not fail if run against an older version of
libjpeg-turbo or against libjpeg v6b until the program actually tries to call
jpeg_mem_src() or jpeg_mem_dest().

Both cjpeg and djpeg have been extended to allow testing the in-memory
source/destination manager functions. See their respective man pages for more
details.


*******************************************************************************
** Mathematical Compatibility
Expand Down
10 changes: 8 additions & 2 deletions cjpeg.1
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.TH CJPEG 1 "1 January 2013"
.TH CJPEG 1 "18 January 2013"
.SH NAME
cjpeg \- compress an image file to a JPEG file
.SH SYNOPSIS
Expand Down Expand Up @@ -195,6 +195,11 @@ selects 4000000 bytes. If more space is needed, temporary files will be used.
.BI \-outfile " name"
Send output image to the named file, not to standard output.
.TP
.BI \-memdst
Compress to memory instead of a file. This feature was implemented mainly as a
way of testing the in-memory destination manager (jpeg_mem_dest()), but it is
also useful for benchmarking, since it reduces the I/O overhead.
.TP
.B \-verbose
Enable debug printout. More
.BR \-v 's
Expand Down Expand Up @@ -315,7 +320,8 @@ Communications of the ACM, April 1991 (vol. 34, no. 4), pp. 30-44.
Independent JPEG Group
.PP
This file was modified by The libjpeg-turbo Project to include only information
relevant to libjpeg-turbo and to wordsmith certain sections.
relevant to libjpeg-turbo, to wordsmith certain sections, and to describe
features not present in libjpeg.
.SH BUGS
Support for GIF input files was removed in cjpeg v6b due to concerns over
the Unisys LZW patent. Although this patent expired in 2006, cjpeg still
Expand Down
72 changes: 51 additions & 21 deletions cjpeg.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* Copyright (C) 1991-1998, Thomas G. Lane.
* Modified 2003-2011 by Guido Vollbeding.
* Modifications:
* Copyright (C) 2010, D. R. Commander.
* Copyright (C) 2010, 2013, D. R. Commander.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains a command-line user interface for the JPEG compressor.
Expand Down Expand Up @@ -139,6 +139,7 @@ select_file_type (j_compress_ptr cinfo, FILE * infile)

static const char * progname; /* program name for error messages */
static char * outfilename; /* for -outfile switch */
boolean memdst; /* for -memdst switch */


LOCAL(void)
Expand Down Expand Up @@ -187,6 +188,9 @@ usage (void)
#endif
fprintf(stderr, " -maxmemory N Maximum memory to use (in kbytes)\n");
fprintf(stderr, " -outfile name Specify name for output file\n");
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
fprintf(stderr, " -memdst Compress to memory instead of file (useful for benchmarking)\n");
#endif
fprintf(stderr, " -verbose or -debug Emit debug output\n");
fprintf(stderr, "Switches for wizards:\n");
fprintf(stderr, " -baseline Force baseline quantization tables\n");
Expand Down Expand Up @@ -228,6 +232,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
simple_progressive = FALSE;
is_targa = FALSE;
outfilename = NULL;
memdst = FALSE;
cinfo->err->trace_level = 0;

/* Scan command line options, adjust parameters */
Expand Down Expand Up @@ -312,7 +317,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
#ifdef ENTROPY_OPT_SUPPORTED
cinfo->optimize_coding = TRUE;
#else
fprintf(stderr, "%s: sorry, entropy optimization was not compiled\n",
fprintf(stderr, "%s: sorry, entropy optimization was not compiled in\n",
progname);
exit(EXIT_FAILURE);
#endif
Expand All @@ -329,11 +334,21 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
simple_progressive = TRUE;
/* We must postpone execution until num_components is known. */
#else
fprintf(stderr, "%s: sorry, progressive output was not compiled\n",
fprintf(stderr, "%s: sorry, progressive output was not compiled in\n",
progname);
exit(EXIT_FAILURE);
#endif

} else if (keymatch(arg, "memdst", 2)) {
/* Use in-memory destination manager */
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
memdst = TRUE;
#else
fprintf(stderr, "%s: sorry, in-memory destination manager was not compiled in\n",
progname);
exit(EXIT_FAILURE);
#endif

} else if (keymatch(arg, "quality", 1)) {
/* Quality ratings (quantization table scaling factors). */
if (++argn >= argc) /* advance to next argument */
Expand Down Expand Up @@ -394,7 +409,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
scansarg = argv[argn];
/* We must postpone reading the file in case -progressive appears. */
#else
fprintf(stderr, "%s: sorry, multi-scan output was not compiled\n",
fprintf(stderr, "%s: sorry, multi-scan output was not compiled in\n",
progname);
exit(EXIT_FAILURE);
#endif
Expand Down Expand Up @@ -473,7 +488,9 @@ main (int argc, char **argv)
int file_index;
cjpeg_source_ptr src_mgr;
FILE * input_file;
FILE * output_file;
FILE * output_file = NULL;
unsigned char *outbuffer = NULL;
unsigned long outsize = 0;
JDIMENSION num_scanlines;

/* On Mac, fetch a command line. */
Expand Down Expand Up @@ -516,19 +533,21 @@ main (int argc, char **argv)
file_index = parse_switches(&cinfo, argc, argv, 0, FALSE);

#ifdef TWO_FILE_COMMANDLINE
/* Must have either -outfile switch or explicit output file name */
if (outfilename == NULL) {
if (file_index != argc-2) {
fprintf(stderr, "%s: must name one input and one output file\n",
progname);
usage();
}
outfilename = argv[file_index+1];
} else {
if (file_index != argc-1) {
fprintf(stderr, "%s: must name one input and one output file\n",
progname);
usage();
if (!memdst) {
/* Must have either -outfile switch or explicit output file name */
if (outfilename == NULL) {
if (file_index != argc-2) {
fprintf(stderr, "%s: must name one input and one output file\n",
progname);
usage();
}
outfilename = argv[file_index+1];
} else {
if (file_index != argc-1) {
fprintf(stderr, "%s: must name one input and one output file\n",
progname);
usage();
}
}
}
#else
Expand Down Expand Up @@ -556,7 +575,7 @@ main (int argc, char **argv)
fprintf(stderr, "%s: can't open %s\n", progname, outfilename);
exit(EXIT_FAILURE);
}
} else {
} else if (!memdst) {
/* default output file is stdout */
output_file = write_stdout();
}
Expand All @@ -579,7 +598,12 @@ main (int argc, char **argv)
file_index = parse_switches(&cinfo, argc, argv, 0, TRUE);

/* Specify data destination for compression */
jpeg_stdio_dest(&cinfo, output_file);
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
if (memdst)
jpeg_mem_dest(&cinfo, &outbuffer, &outsize);
else
#endif
jpeg_stdio_dest(&cinfo, output_file);

/* Start compressor */
jpeg_start_compress(&cinfo, TRUE);
Expand All @@ -598,13 +622,19 @@ main (int argc, char **argv)
/* Close files, if we opened them */
if (input_file != stdin)
fclose(input_file);
if (output_file != stdout)
if (output_file != stdout && output_file != NULL)
fclose(output_file);

#ifdef PROGRESS_REPORT
end_progress_monitor((j_common_ptr) &cinfo);
#endif

if (memdst) {
fprintf(stderr, "Compressed size: %lu bytes\n", outsize);
if (outbuffer != NULL)
free(outbuffer);
}

/* All done. */
exit(jerr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS);
return 0; /* suppress no-return-value warnings */
Expand Down
25 changes: 23 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ AC_SUBST(JPEG_LIB_VERSION_DECIMAL)
AC_MSG_RESULT([$JPEG_LIB_VERSION_DECIMAL])
AC_DEFINE_UNQUOTED(JPEG_LIB_VERSION, [$JPEG_LIB_VERSION], [libjpeg API version])

AC_MSG_CHECKING([libjpeg shared library version])
AC_ARG_VAR(SO_MAJOR_VERSION, [Major version of the libjpeg-turbo shared library (default is determined by the API version)])
AC_ARG_VAR(SO_MINOR_VERSION, [Minor version of the libjpeg-turbo shared library (default is determined by the API version)])
if test "x$SO_MAJOR_VERSION" = "x"; then
Expand All @@ -136,9 +135,31 @@ if test "x$SO_MINOR_VERSION" = "x"; then
*) SO_MINOR_VERSION=0 ;;
esac
fi
AC_MSG_RESULT([$SO_MAJOR_VERSION:$SO_MINOR_VERSION])

# Memory source/destination managers
SO_AGE=0
MEM_SRCDST_FUNCTIONS=
if test "x${with_jpeg8}" != "xyes"; then
AC_MSG_CHECKING([whether to include in-memory source/destination managers])
AC_ARG_WITH([mem-srcdst],
AC_HELP_STRING([--without-mem-srcdst], [Do not include in-memory source/destination manager functions when emulating the libjpeg v6b or v7 API/ABI]))
if test "x$with_mem_srcdst" != "xno"; then
AC_MSG_RESULT(yes)
AC_DEFINE([MEM_SRCDST_SUPPORTED], [1], [Support in-memory source/destination managers])
SO_AGE=1
MEM_SRCDST_FUNCTIONS="global: jpeg_mem_dest; jpeg_mem_src;";
else
AC_MSG_RESULT(no)
fi
fi

AC_MSG_CHECKING([libjpeg shared library version])
AC_MSG_RESULT([$SO_MAJOR_VERSION.$SO_AGE.$SO_MINOR_VERSION])
SO_MAJOR_VERSION=`expr $SO_MAJOR_VERSION + $SO_AGE`
AC_SUBST(SO_MAJOR_VERSION)
AC_SUBST(SO_MINOR_VERSION)
AC_SUBST(SO_AGE)
AC_SUBST(MEM_SRCDST_FUNCTIONS)

AC_DEFINE_UNQUOTED(LIBJPEG_TURBO_VERSION, [$VERSION], [libjpeg-turbo version])

Expand Down
9 changes: 7 additions & 2 deletions djpeg.1
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.TH DJPEG 1 "1 January 2013"
.TH DJPEG 1 "18 January 2013"
.SH NAME
djpeg \- decompress a JPEG file to an image file
.SH SYNOPSIS
Expand Down Expand Up @@ -173,6 +173,10 @@ selects 4000000 bytes. If more space is needed, temporary files will be used.
.BI \-outfile " name"
Send output image to the named file, not to standard output.
.TP
.BI \-memsrc
Load input file into memory before decompressing. This feature was implemented
mainly as a way of testing the in-memory source manager (jpeg_mem_src().)
.TP
.B \-verbose
Enable debug printout. More
.BR \-v 's
Expand Down Expand Up @@ -245,7 +249,8 @@ Communications of the ACM, April 1991 (vol. 34, no. 4), pp. 30-44.
Independent JPEG Group
.PP
This file was modified by The libjpeg-turbo Project to include only information
relevant to libjpeg-turbo and to wordsmith certain sections.
relevant to libjpeg-turbo, to wordsmith certain sections, and to describe
features not present in libjpeg.
.SH BUGS
To avoid the Unisys LZW patent,
.B djpeg
Expand Down
Loading

0 comments on commit ab70623

Please sign in to comment.