Compare commits

..

60 Commits
v1.0.1 ... v2.0

Author SHA1 Message Date
Frank Bossen
62300280b5 Update MS-SSIM tuning
Change optimization parameters when tuning for MS-SSIM for better
performance
2014-07-10 16:55:53 +09:00
Frank Bossen
55e3e7e819 Fix #64
Setting a user-defined quality level in cjpeg was incorrectly setting
quantization table
2014-07-09 11:37:36 +09:00
Josh Aas
0c59a4daf6 Merge pull request #62 from negge/master
Updating yuvjpeg and jpegyuv to match Daala tools.
2014-07-07 13:07:07 -05:00
Nathan E. Egge
d47fa82ae8 Updating yuvjpeg and jpegyuv to match Daala tools.
Add support for jpeg images with non-multiple of 16 sizes.
2014-07-07 13:46:59 -04:00
Frank Bossen
c3b7375ad8 Fix #56 2014-06-26 12:45:03 -04:00
Frank Bossen
b8c8ef9851 Silence compiler warning
gcc 4.8 was throwing 'foo' may be used uninitialized in this function
[-Wmaybe-uninitialized]
2014-06-04 16:31:27 +02:00
Frank Bossen
a9356f18b4 Silence compiler warning 2014-05-30 03:18:37 +02:00
Frank Bossen
5dc78b3681 Merge branch 'jpegin' 2014-05-30 03:15:46 +02:00
Frank Bossen
66bf3abec7 Improve support of JPEG input in cjpeg
Add macro JPEG_RAW_READER that defines whether to pass RAW sample data
from input to output JPEG files (hence preserving color space and
sampling). Macro is now disabled by default.
Add code to copy metadata from input to output JPEG, hence preserving
color profiles and other important information
2014-05-30 03:14:09 +02:00
Frank Bossen
535b1ee3ef Fix issue with JPEG read in cjpeg
Color space and sampling was not properly configured leading to errors
when encoding from a JPEG file.
2014-05-16 16:33:10 -04:00
Frank Bossen
e170b61137 Add support for JPEG input in cjpeg 2014-05-16 11:00:34 -04:00
Frank Bossen
ea4fad9aec Fix #50
Make trellis work with DCT implementations other than the default:
scale and store transform coefficients for trellis
2014-05-10 14:59:58 -04:00
Frank Bossen
4b1094cc3a Disable trellis in jpegtran
Trellis quantization is not supposed to be enabled in the jpegtran
application as it does not perform transform and quantization.
Should fix #49
2014-05-10 08:19:31 -04:00
Josh Aas
3f1e5d6842 Update version to 2.0pre. 2014-05-09 22:11:12 -05:00
Frank Bossen
93da07241d Merge branch 'trellis' 2014-05-09 18:28:26 -04:00
Frank Bossen
87254c1c44 Use single DC scan by default
Value of cinfo->one_dc_scan is set to true by default to use a single
DC scan for all components.
Option -onedcscan is replaced by -multidcscan to enable multiple DC
scans.
While this change appears to degrade compression performance it
improves compatibility with a wider range of JPEG decoders.
2014-05-09 10:46:00 -04:00
Josh Aas
a5195816f6 Add configure check for libm/pow. Fixes Linux build issue. 2014-05-08 22:25:29 -05:00
Frank Bossen
13e2115054 Add option to have single DC scan
Add option to have a single DC scan wherein all components are
interleaved when using progressive mode. This may resolve compatibility
issues raised in #29 and #48.
This option is available through -onedcscan in cjpeg
2014-05-08 17:33:14 -04:00
Frank Bossen
8a99fcac80 Correct comment 2014-05-08 17:00:53 -04:00
Frank Bossen
061d42c272 Fix #47
When specifying -debug or -verbose in the cjpeg application the scans
selected by the scan optimization process are printed to stderr
2014-05-08 16:44:33 -04:00
Frank Bossen
d236890325 Update copyright headers/statements 2014-05-08 16:42:51 -04:00
Frank Bossen
c8e03dbda5 Fix issue with trellis and no scan opt
Disabling scan optimization with trellis enabled was leading to
incorrect results
2014-05-08 15:50:22 -04:00
Frank Bossen
8b8d88c850 Improve cjpeg help text
List options related to trellis quantization in cjpeg help text
2014-05-05 11:38:43 -04:00
Frank Bossen
a5403fda93 Remove outdated and incorrect comment 2014-05-05 11:31:34 -04:00
Frank Bossen
c88aade31c Revert type change
Revert type of use_moz_defaults to boolean
2014-04-30 14:54:18 -04:00
Frank Bossen
101df25fde Modify trellis parameter defaults
Modify trellis parameters to optimize for PSNR-HVS by default
2014-04-29 14:03:34 -04:00
Frank Bossen
21b2f11a42 Fix issue with quantization matrix optimization
Update quantization matrix in trellis loop
2014-04-29 13:00:50 -04:00
Frank Bossen
cd3c32f15d Update trellis optimization parameters
Slightly improved parameters are provided when optimizing for SSIM
metric
2014-04-29 12:33:46 -04:00
Frank Bossen
87d506416f Fix issue when trellis is disabled
master->pass_number_scan_opt_base needs to be set to appropriate value
when trellis is disabled
2014-04-29 12:32:05 -04:00
Frank Bossen
b03b5797f4 Add optimization of quantization matrix
Optimizes quantization matrix by minimizing reconstruction error based
on quantized coefficients.
Feature is controlled by cinfo->trellis_q_opt; disabled by default.
2014-04-28 16:28:05 -04:00
Frank Bossen
e5f8575776 Add option to tune for MS-SSIM
Added -tune-ms-ssim option to cjpeg to tune for multiscale SSIM metric
2014-04-27 22:01:40 -04:00
Josh Aas
b36bec4d71 Merge pull request #44 from h0r14/master
turbojpeg warning [-Wattributes]
2014-04-27 20:47:01 -05:00
Horia Racoviceanu
62003f9ae5 turbojpeg warning [-Wattributes]
warning: always_inline function might not be inlinable
Patch from http://sourceforge.net/p/libjpeg-turbo/patches/56/
2014-04-27 02:39:59 +00:00
Josh Aas
7d7e24c60a Merge pull request #43 from reubenhwk/cleanup_v2
Cleanup v2
2014-04-24 08:22:24 -05:00
Reuben Hawkins
b4c7d90b3f bump version to v1.0.2 2014-04-23 20:19:47 -05:00
Reuben Hawkins
e4fa772b58 adjust_exif_parameters only needed in JPEG_LIB_VER > 70
The invocation of this function is wrapped in an ifdef JPEGLIB >70
but the definition of the function wasn't.  This change adds the
ifdef around the function definition.
2014-04-23 20:19:47 -05:00
Reuben Hawkins
2086f28340 tjbench.c: return retval in funcs defining it
the throw macros set retval, but not all functions use/return this
value.  This change, mainly to clean up compiler warnings, makes
those functions return a value.
2014-04-23 20:19:47 -05:00
Reuben Hawkins
548aeb977d turbojpeg.c: clean up warnings around getinstance
This macro defined two local variables, cinfo and dinfo, but both
aren't always used.  Add a (void)cinfo; and (void)dinfo in there
to hush up the compiler.
2014-04-17 23:00:01 -05:00
Reuben Hawkins
b93b80b3aa jcmaster.c: fix compiler warnings
* remove unused variable size[8]
* initialize base_scan_idx
2014-04-17 23:00:01 -05:00
Reuben Hawkins
706f2a8881 configure.ac: fix INLINE definition
The inline attribute must still be prefixed with 'inline' to work
correctly.
2014-04-17 23:00:01 -05:00
Reuben Hawkins
abffeb8390 configure.ac: enable silent build rules
Silent build rules make it much less likely for warnings to go by
unnoticed.
2014-04-17 23:00:01 -05:00
Reuben Hawkins
bd845c8691 configure.ac: fix some autoconf warnings 2014-04-17 23:00:01 -05:00
Reuben Hawkins
4e5e4787e4 configure.ac: use AC_LANG_SOURCE where appropriate 2014-04-17 23:00:01 -05:00
Reuben Hawkins
100ed0a5f9 bump version to v1.0.1 2014-04-17 23:00:01 -05:00
Frank Bossen
45c800e2d6 Fix #40
Improve code portability to deal with cases where:
- right shift is always unsigned
- size of int is not 32 bits
2014-04-15 18:17:09 +02:00
Frank Bossen
3fd6eec30b Remove comment on portability
Derivation of sign value relies on shift right operator >> being an
arithmetic shift. It is thus not strictly portable since the C standard
defines the result of x >> y as "implementation-defined" when x is a
signed integer with a negative value.
2014-04-15 15:23:30 +02:00
Frank Bossen
d273dc190c Fix #39
Avoid declaring variable in middle of code block
2014-04-15 15:07:55 +02:00
fbossen
5d4e113b06 Merge pull request #38 from pengvado/master
36% faster encode_mcu_AC_first(), by eliminating an unpredictable branch in the inner loop
2014-04-15 01:57:12 +02:00
Loren Merritt
8db334cde2 36% faster encode_mcu_AC_first(), by eliminating an unpredictable branch in the inner loop
Which corresponds to 15% faster overall encoding in "progressive scan optimization" mode.
(And a negligible speedup in -fastcrush mode.)
2014-04-13 05:30:44 +00:00
Frank Bossen
1733487e17 Add option to perform multiple trellis quantization iterations
Multiple trellis iterations may improve coding performance as Huffman
tables are updated with each iteration. In practice the benefit appears
to be very minimal
2014-04-01 23:14:29 +02:00
Frank Bossen
2012e32f19 Update trellis quantization to support progressive coding mode
Trellis quantization is modified:
- to work on the configurable spectral range Ss to Se
- to optionally optimize runs of EOBs
- to optionally split optimization between 2 spectral ranges
In trellis quantization passes Huffman table code optimization is
modified such as to generable a valid code length for each possible
symbol by resetting frequency counters to 1 instead of 0
2014-04-01 20:14:37 +02:00
Josh Aas
f4c556031c Merge pull request #32 from elfring/Complete_quoting_for_parameters_of_some_CMake_commands
Complete quoting for parameters of some CMake commands.
2014-04-01 11:46:48 -05:00
Markus Elfring
553e2cb89e Bug #17: Completed quoting for parameters of some CMake commands
A wiki article pointed out that whitespace will only be preserved for parameters
in CMake commands if passed strings will be appropriately quoted or escaped.
http://cmake.org/Wiki/CMake/Language_Syntax#CMake_splits_arguments_unless_you_use_quotation_marks_or_escapes.

Quoting was added so that more places should also handle file names correctly
which contain space characters or semicolons eventually.

Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
2014-04-01 17:47:42 +02:00
Frank Bossen
4d0329b235 Add option to disable trellis quantization 2014-03-28 18:16:46 +01:00
Frank Bossen
199fffb759 Enable combination of trellis quantization and scan optimization 2014-03-28 12:42:37 +01:00
Frank Bossen
2de8e97989 Add option to use lambda weighting table
Different lambda values may be used for each frequency in DCT domain.
The weighting table is currently not configurable but can be
enabled/disabled with cinfo-> use_lambda_weight_tbl
2014-03-26 00:06:07 +01:00
Frank Bossen
6f168e4f80 Add parameters to cjpeg to tune for different metrics
-tune-psnr, -tune-ssim and -tune-hvs-psnr are added to cjpeg to control
the trellis quantization process and optimize output for PSNR, SSIM and
HVS-PSNR distortion metrics
2014-03-25 11:48:30 +01:00
Frank Bossen
3e8afe7f94 Add option to control lambda parameter from command line
-lambda1 and -lambda2 command line parameters are added to cjpeg to
control trellis quantization
2014-03-24 20:51:46 +01:00
Frank Bossen
758ed27a05 Add option to use flat quantization table
Set cinfo->use_flat_quant_tbl to TRUE to use flat quantization table or
-flat option in cjpeg
2014-03-24 16:30:56 +01:00
Frank Bossen
d200b2c144 Initial implementation of trellis quantization
A new pass type trellis_pass is added. It defines a pass where trellis
quantization is done in the quantize_trellis() function.
Trellis quantization can be enabled by setting use_moz_defaults to 2 or
by using the -trellis option in cjpeg
Note that trellis does currently not work with scan optimization. Scan
optimization is disabled when trellis is enabled.
2014-03-23 21:06:01 +01:00
29 changed files with 1325 additions and 277 deletions

View File

@@ -5,11 +5,11 @@
cmake_minimum_required(VERSION 2.6)
project(libmozjpeg C)
set(VERSION 1.0.0)
set(VERSION 2.0pre)
if(MINGW OR CYGWIN)
execute_process(COMMAND "date" "+%Y%m%d" OUTPUT_VARIABLE BUILD)
string(REGEX REPLACE "\n" "" BUILD ${BUILD})
string(REGEX REPLACE "\n" "" BUILD "${BUILD}")
elseif(WIN32)
execute_process(COMMAND "wmic.exe" "os" "get" "LocalDateTime" OUTPUT_VARIABLE
BUILD)
@@ -141,7 +141,7 @@ message(STATUS "Install directory = ${CMAKE_INSTALL_PREFIX}")
configure_file(win/jconfig.h.in jconfig.h)
configure_file(win/config.h.in config.h)
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR})
include_directories("${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_SOURCE_DIR}")
if(WITH_JAVA)
find_package(Java)
@@ -247,7 +247,7 @@ set_property(TARGET tjbench-static PROPERTY COMPILE_FLAGS
"-DBMP_SUPPORTED -DPPM_SUPPORTED")
add_executable(cjpeg-static cjpeg.c cdjpeg.c rdbmp.c rdgif.c rdppm.c rdswitch.c
rdtarga.c)
rdtarga.c rdjpeg.c)
set_property(TARGET cjpeg-static PROPERTY COMPILE_FLAGS
"-DBMP_SUPPORTED -DGIF_SUPPORTED -DPPM_SUPPORTED -DTARGA_SUPPORTED -DUSE_SETMODE")
target_link_libraries(cjpeg-static jpeg-static)
@@ -313,133 +313,133 @@ set(MD5_JPEG_PROG_ARI 0a8f1c8f66e113c3cf635df0a475a617)
set(MD5_JPEG_CROP b4197f377e621c4e9b1d20471432610d)
if(WITH_JAVA)
add_test(TJUnitTest ${JAVA_RUNTIME} -cp java/${OBJDIR}turbojpeg.jar -Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}/${OBJDIR} TJUnitTest)
add_test(TJUnitTest-yuv ${JAVA_RUNTIME} -cp java/${OBJDIR}turbojpeg.jar -Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}/${OBJDIR} TJUnitTest -yuv)
add_test(TJUnitTest-yuv-nopad ${JAVA_RUNTIME} -cp java/${OBJDIR}turbojpeg.jar -Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}/${OBJDIR} TJUnitTest -yuv -noyuvpad)
add_test(TJUnitTest-bi ${JAVA_RUNTIME} -cp java/${OBJDIR}turbojpeg.jar -Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}/${OBJDIR} TJUnitTest -bi)
add_test(TJUnitTest-bi-yuv ${JAVA_RUNTIME} -cp java/${OBJDIR}turbojpeg.jar -Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}/${OBJDIR} TJUnitTest -bi -yuv)
add_test(TJUnitTest-bi-yuv-nopad ${JAVA_RUNTIME} -cp java/${OBJDIR}turbojpeg.jar -Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}/${OBJDIR} TJUnitTest -bi -yuv -noyuvpad)
add_test(TJUnitTest ${JAVA_RUNTIME} -cp "java/${OBJDIR}turbojpeg.jar" "-Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}/${OBJDIR}" TJUnitTest)
add_test(TJUnitTest-yuv ${JAVA_RUNTIME} -cp "java/${OBJDIR}turbojpeg.jar" "-Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}/${OBJDIR}" TJUnitTest -yuv)
add_test(TJUnitTest-yuv-nopad ${JAVA_RUNTIME} -cp "java/${OBJDIR}turbojpeg.jar" "-Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}/${OBJDIR}" TJUnitTest -yuv -noyuvpad)
add_test(TJUnitTest-bi ${JAVA_RUNTIME} -cp "java/${OBJDIR}turbojpeg.jar" "-Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}/${OBJDIR}" TJUnitTest -bi)
add_test(TJUnitTest-bi-yuv ${JAVA_RUNTIME} -cp "java/${OBJDIR}turbojpeg.jar" "-Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}/${OBJDIR}" TJUnitTest -bi -yuv)
add_test(TJUnitTest-bi-yuv-nopad ${JAVA_RUNTIME} -cp "java/${OBJDIR}turbojpeg.jar" "-Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}/${OBJDIR}" TJUnitTest -bi -yuv -noyuvpad)
endif()
add_test(tjunittest tjunittest)
add_test(tjunittest-alloc tjunittest -alloc)
add_test(tjunittest-yuv tjunittest -yuv)
add_test(tjunittest-yuv-alloc tjunittest -yuv -alloc)
add_test(tjunittest-yuv-nopad tjunittest -yuv -noyuvpad)
add_test(cjpeg-int sharedlib/cjpeg -dct int -outfile testoutint.jpg ${CMAKE_SOURCE_DIR}/testimages/testorig.ppm)
add_test(cjpeg-int-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_INT} -DFILE=testoutint.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(cjpeg-fast sharedlib/cjpeg -dct fast -opt -outfile testoutfst.jpg ${CMAKE_SOURCE_DIR}/testimages/testorig.ppm)
add_test(cjpeg-fast-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_FAST} -DFILE=testoutfst.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(cjpeg-fast-100 sharedlib/cjpeg -dct fast -quality 100 -opt -outfile testoutfst100.jpg ${CMAKE_SOURCE_DIR}/testimages/testorig.ppm)
add_test(cjpeg-fast-100-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_FAST_100} -DFILE=testoutfst100.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(cjpeg-float sharedlib/cjpeg -dct float -outfile testoutflt.jpg ${CMAKE_SOURCE_DIR}/testimages/testorig.ppm)
add_test(cjpeg-int sharedlib/cjpeg -dct int -outfile testoutint.jpg "${CMAKE_SOURCE_DIR}/testimages/testorig.ppm")
add_test(cjpeg-int-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_JPEG_INT} -DFILE=testoutint.jpg -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
add_test(cjpeg-fast sharedlib/cjpeg -dct fast -opt -outfile testoutfst.jpg "${CMAKE_SOURCE_DIR}/testimages/testorig.ppm")
add_test(cjpeg-fast-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_JPEG_FAST} -DFILE=testoutfst.jpg -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
add_test(cjpeg-fast-100 sharedlib/cjpeg -dct fast -quality 100 -opt -outfile testoutfst100.jpg "${CMAKE_SOURCE_DIR}/testimages/testorig.ppm")
add_test(cjpeg-fast-100-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_JPEG_FAST_100} -DFILE=testoutfst100.jpg -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
add_test(cjpeg-float sharedlib/cjpeg -dct float -outfile testoutflt.jpg "${CMAKE_SOURCE_DIR}/testimages/testorig.ppm")
if(WITH_SIMD)
add_test(cjpeg-float-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_FLOAT} -DFILE=testoutflt.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(cjpeg-float-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_JPEG_FLOAT} -DFILE=testoutflt.jpg -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
else()
add_test(cjpeg-float-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_FLOAT_NOSIMD} -DFILE=testoutflt.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(cjpeg-float-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_JPEG_FLOAT_NOSIMD} -DFILE=testoutflt.jpg -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
endif()
add_test(cjpeg-int-gray sharedlib/cjpeg -dct int -grayscale -outfile testoutgray.jpg ${CMAKE_SOURCE_DIR}/testimages/testorig.ppm)
add_test(cjpeg-int-gray-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_INT_GRAY} -DFILE=testoutgray.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(djpeg-int sharedlib/djpeg -dct int -fast -ppm -outfile testoutint.ppm ${CMAKE_SOURCE_DIR}/testimages/testorig.jpg)
add_test(djpeg-int-cmp ${CMAKE_COMMAND} -DMD5=${MD5_PPM_INT} -DFILE=testoutint.ppm -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(djpeg-fast sharedlib/djpeg -dct fast -ppm -outfile testoutfst.ppm ${CMAKE_SOURCE_DIR}/testimages/testorig.jpg)
add_test(djpeg-fast-cmp ${CMAKE_COMMAND} -DMD5=${MD5_PPM_FAST} -DFILE=testoutfst.ppm -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(djpeg-float sharedlib/djpeg -dct float -ppm -outfile testoutflt.ppm ${CMAKE_SOURCE_DIR}/testimages/testorig.jpg)
add_test(cjpeg-int-gray sharedlib/cjpeg -dct int -grayscale -outfile testoutgray.jpg "${CMAKE_SOURCE_DIR}/testimages/testorig.ppm")
add_test(cjpeg-int-gray-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_JPEG_INT_GRAY} -DFILE=testoutgray.jpg -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
add_test(djpeg-int sharedlib/djpeg -dct int -fast -ppm -outfile testoutint.ppm "${CMAKE_SOURCE_DIR}/testimages/testorig.jpg")
add_test(djpeg-int-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_PPM_INT} -DFILE=testoutint.ppm -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
add_test(djpeg-fast sharedlib/djpeg -dct fast -ppm -outfile testoutfst.ppm "${CMAKE_SOURCE_DIR}/testimages/testorig.jpg")
add_test(djpeg-fast-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_PPM_FAST} -DFILE=testoutfst.ppm -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
add_test(djpeg-float sharedlib/djpeg -dct float -ppm -outfile testoutflt.ppm "${CMAKE_SOURCE_DIR}/testimages/testorig.jpg")
if(WITH_SIMD)
add_test(djpeg-float-cmp ${CMAKE_COMMAND} -DMD5=${MD5_PPM_FLOAT} -DFILE=testoutflt.ppm -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(djpeg-float-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_PPM_FLOAT} -DFILE=testoutflt.ppm -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
else()
add_test(djpeg-float-cmp ${CMAKE_COMMAND} -DMD5=${MD5_PPM_FLOAT_NOSIMD} -DFILE=testoutflt.ppm -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(djpeg-float-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_PPM_FLOAT_NOSIMD} -DFILE=testoutflt.ppm -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
endif()
foreach(scale 2_1 15_8 7_4 13_8 3_2 11_8 5_4 9_8 7_8 3_4 5_8 1_2 3_8 1_4 1_8)
string(REGEX REPLACE "_" "/" scalearg ${scale})
add_test(djpeg-int-${scale} sharedlib/djpeg -dct int -nosmooth -scale ${scalearg} -ppm -outfile testoutint${scale}.ppm ${CMAKE_SOURCE_DIR}/testimages/testorig.jpg)
add_test(djpeg-int-${scale}-cmp ${CMAKE_COMMAND} -DMD5=${MD5_PPM_INT_${scale}} -DFILE=testoutint${scale}.ppm -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(djpeg-int-${scale} sharedlib/djpeg -dct int -nosmooth -scale ${scalearg} -ppm -outfile testoutint${scale}.ppm "${CMAKE_SOURCE_DIR}/testimages/testorig.jpg")
add_test(djpeg-int-${scale}-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_PPM_INT_${scale}} -DFILE=testoutint${scale}.ppm -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
endforeach()
add_test(djpeg-fast-1_2 sharedlib/djpeg -dct fast -scale 1/2 -ppm -outfile testoutfst1_2.ppm ${CMAKE_SOURCE_DIR}/testimages/testorig.jpg)
add_test(djpeg-fast-1_2-cmp ${CMAKE_COMMAND} -DMD5=${MD5_PPM_FAST_1_2} -DFILE=testoutfst1_2.ppm -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(djpeg-256 sharedlib/djpeg -dct int -bmp -colors 256 -outfile testout.bmp ${CMAKE_SOURCE_DIR}/testimages/testorig.jpg)
add_test(djpeg-256-cmp ${CMAKE_COMMAND} -DMD5=${MD5_BMP_256} -DFILE=testout.bmp -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(cjpeg-prog sharedlib/cjpeg -dct int -progressive -outfile testoutp.jpg ${CMAKE_SOURCE_DIR}/testimages/testorig.ppm)
add_test(cjpeg-prog-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_PROG} -DFILE=testoutp.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(jpegtran-prog sharedlib/jpegtran -outfile testoutt.jpg testoutp.jpg)
add_test(jpegtran-prog-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_INT} -DFILE=testoutt.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(djpeg-fast-1_2 sharedlib/djpeg -dct fast -scale 1/2 -ppm -outfile testoutfst1_2.ppm "${CMAKE_SOURCE_DIR}/testimages/testorig.jpg")
add_test(djpeg-fast-1_2-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_PPM_FAST_1_2} -DFILE=testoutfst1_2.ppm -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
add_test(djpeg-256 sharedlib/djpeg -dct int -bmp -colors 256 -outfile testout.bmp "${CMAKE_SOURCE_DIR}/testimages/testorig.jpg")
add_test(djpeg-256-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_BMP_256} -DFILE=testout.bmp -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
add_test(cjpeg-prog sharedlib/cjpeg -dct int -progressive -outfile testoutp.jpg "${CMAKE_SOURCE_DIR}/testimages/testorig.ppm")
add_test(cjpeg-prog-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_JPEG_PROG} -DFILE=testoutp.jpg -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
add_test(jpegtran-prog sharedlib/jpegtran -outfile testoutt.jpg testoutp.jpg")
add_test(jpegtran-prog-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_JPEG_INT} -DFILE=testoutt.jpg -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
if(WITH_ARITH_ENC)
add_test(cjpeg-ari sharedlib/cjpeg -dct int -arithmetic -outfile testoutari.jpg ${CMAKE_SOURCE_DIR}/testimages/testorig.ppm)
add_test(cjpeg-ari-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_ARI} -DFILE=testoutari.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake )
add_test(jpegtran-toari sharedlib/jpegtran -arithmetic -outfile testouta.jpg ${CMAKE_SOURCE_DIR}/testimages/testimgint.jpg)
add_test(jpegtran-toari-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_ARI} -DFILE=testouta.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(cjpeg-prog-ari sharedlib/cjpeg -dct int -progressive -arithmetic -sample 1x1 -outfile testoutpa.jpg ${CMAKE_SOURCE_DIR}/testimages/testorig.ppm)
add_test(cjpeg-prog-ari-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_PROG_ARI} -DFILE=testoutpa.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake )
add_test(cjpeg-ari sharedlib/cjpeg -dct int -arithmetic -outfile testoutari.jpg "${CMAKE_SOURCE_DIR}/testimages/testorig.ppm")
add_test(cjpeg-ari-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_JPEG_ARI} -DFILE=testoutari.jpg -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
add_test(jpegtran-toari sharedlib/jpegtran -arithmetic -outfile testouta.jpg "${CMAKE_SOURCE_DIR}/testimages/testimgint.jpg")
add_test(jpegtran-toari-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_JPEG_ARI} -DFILE=testouta.jpg -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
add_test(cjpeg-prog-ari sharedlib/cjpeg -dct int -progressive -arithmetic -sample 1x1 -outfile testoutpa.jpg "${CMAKE_SOURCE_DIR}/testimages/testorig.ppm")
add_test(cjpeg-prog-ari-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_JPEG_PROG_ARI} -DFILE=testoutpa.jpg -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
endif()
if(WITH_ARITH_DEC)
add_test(djpeg-ari sharedlib/djpeg -dct int -fast -ppm -outfile testoutari.ppm ${CMAKE_SOURCE_DIR}/testimages/testimgari.jpg)
add_test(djpeg-ari-cmp ${CMAKE_COMMAND} -DMD5=${MD5_PPM_ARI} -DFILE=testoutari.ppm -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(jpegtran-fromari sharedlib/jpegtran -outfile testouta.jpg ${CMAKE_SOURCE_DIR}/testimages/testimgari.jpg)
add_test(jpegtran-fromari-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_INT} -DFILE=testouta.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(djpeg-ari sharedlib/djpeg -dct int -fast -ppm -outfile testoutari.ppm "${CMAKE_SOURCE_DIR}/testimages/testimgari.jpg")
add_test(djpeg-ari-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_PPM_ARI} -DFILE=testoutari.ppm -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
add_test(jpegtran-fromari sharedlib/jpegtran -outfile testouta.jpg "${CMAKE_SOURCE_DIR}/testimages/testimgari.jpg")
add_test(jpegtran-fromari-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_JPEG_INT} -DFILE=testouta.jpg -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
endif()
add_test(jpegtran-crop sharedlib/jpegtran -crop 120x90+20+50 -transpose -perfect -outfile testoutcrop.jpg ${CMAKE_SOURCE_DIR}/testimages/testorig.jpg)
add_test(jpegtran-crop-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_CROP} -DFILE=testoutcrop.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(jpegtran-crop sharedlib/jpegtran -crop 120x90+20+50 -transpose -perfect -outfile testoutcrop.jpg "${CMAKE_SOURCE_DIR}/testimages/testorig.jpg")
add_test(jpegtran-crop-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_JPEG_CROP} -DFILE=testoutcrop.jpg -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
add_test(tjunittest-static tjunittest-static)
add_test(tjunittest-static-alloc tjunittest-static -alloc)
add_test(tjunittest-static-yuv tjunittest-static -yuv)
add_test(tjunittest-static-yuv-alloc tjunittest-static -yuv -alloc)
add_test(tjunittest-static-yuv-nopad tjunittest-static -yuv -noyuvpad)
add_test(cjpeg-static-int cjpeg-static -dct int -outfile testoutint.jpg ${CMAKE_SOURCE_DIR}/testimages/testorig.ppm)
add_test(cjpeg-static-int-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_INT} -DFILE=testoutint.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(cjpeg-static-fast cjpeg-static -dct fast -opt -outfile testoutfst.jpg ${CMAKE_SOURCE_DIR}/testimages/testorig.ppm)
add_test(cjpeg-static-fast-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_FAST} -DFILE=testoutfst.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(cjpeg-static-fast-100 cjpeg-static -dct fast -quality 100 -opt -outfile testoutfst100.jpg ${CMAKE_SOURCE_DIR}/testimages/testorig.ppm)
add_test(cjpeg-static-fast-100-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_FAST_100} -DFILE=testoutfst100.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(cjpeg-static-float cjpeg-static -dct float -outfile testoutflt.jpg ${CMAKE_SOURCE_DIR}/testimages/testorig.ppm)
add_test(cjpeg-static-int cjpeg-static -dct int -outfile testoutint.jpg "${CMAKE_SOURCE_DIR}/testimages/testorig.ppm")
add_test(cjpeg-static-int-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_JPEG_INT} -DFILE=testoutint.jpg -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
add_test(cjpeg-static-fast cjpeg-static -dct fast -opt -outfile testoutfst.jpg "${CMAKE_SOURCE_DIR}/testimages/testorig.ppm")
add_test(cjpeg-static-fast-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_JPEG_FAST} -DFILE=testoutfst.jpg -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
add_test(cjpeg-static-fast-100 cjpeg-static -dct fast -quality 100 -opt -outfile testoutfst100.jpg "${CMAKE_SOURCE_DIR}/testimages/testorig.ppm")
add_test(cjpeg-static-fast-100-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_JPEG_FAST_100} -DFILE=testoutfst100.jpg -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
add_test(cjpeg-static-float cjpeg-static -dct float -outfile testoutflt.jpg "${CMAKE_SOURCE_DIR}/testimages/testorig.ppm")
if(WITH_SIMD)
add_test(cjpeg-static-float-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_FLOAT} -DFILE=testoutflt.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(cjpeg-static-float-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_JPEG_FLOAT} -DFILE=testoutflt.jpg -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
else()
add_test(cjpeg-static-float-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_FLOAT_NOSIMD} -DFILE=testoutflt.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(cjpeg-static-float-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_JPEG_FLOAT_NOSIMD} -DFILE=testoutflt.jpg -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
endif()
add_test(cjpeg-static-int-gray cjpeg-static -dct int -grayscale -outfile testoutgray.jpg ${CMAKE_SOURCE_DIR}/testimages/testorig.ppm)
add_test(cjpeg-static-int-gray-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_INT_GRAY} -DFILE=testoutgray.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(djpeg-static-int djpeg-static -dct int -fast -ppm -outfile testoutint.ppm ${CMAKE_SOURCE_DIR}/testimages/testorig.jpg)
add_test(djpeg-static-int-cmp ${CMAKE_COMMAND} -DMD5=${MD5_PPM_INT} -DFILE=testoutint.ppm -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(djpeg-static-fast djpeg-static -dct fast -ppm -outfile testoutfst.ppm ${CMAKE_SOURCE_DIR}/testimages/testorig.jpg)
add_test(djpeg-static-fast-cmp ${CMAKE_COMMAND} -DMD5=${MD5_PPM_FAST} -DFILE=testoutfst.ppm -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(djpeg-static-float djpeg-static -dct float -ppm -outfile testoutflt.ppm ${CMAKE_SOURCE_DIR}/testimages/testorig.jpg)
add_test(cjpeg-static-int-gray cjpeg-static -dct int -grayscale -outfile testoutgray.jpg "${CMAKE_SOURCE_DIR}/testimages/testorig.ppm")
add_test(cjpeg-static-int-gray-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_JPEG_INT_GRAY} -DFILE=testoutgray.jpg -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
add_test(djpeg-static-int djpeg-static -dct int -fast -ppm -outfile testoutint.ppm "${CMAKE_SOURCE_DIR}/testimages/testorig.jpg")
add_test(djpeg-static-int-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_PPM_INT} -DFILE=testoutint.ppm -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
add_test(djpeg-static-fast djpeg-static -dct fast -ppm -outfile testoutfst.ppm "${CMAKE_SOURCE_DIR}/testimages/testorig.jpg")
add_test(djpeg-static-fast-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_PPM_FAST} -DFILE=testoutfst.ppm -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
add_test(djpeg-static-float djpeg-static -dct float -ppm -outfile testoutflt.ppm "${CMAKE_SOURCE_DIR}/testimages/testorig.jpg")
if(WITH_SIMD)
add_test(djpeg-static-float-cmp ${CMAKE_COMMAND} -DMD5=${MD5_PPM_FLOAT} -DFILE=testoutflt.ppm -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(djpeg-static-float-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_PPM_FLOAT} -DFILE=testoutflt.ppm -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
else()
add_test(djpeg-static-float-cmp ${CMAKE_COMMAND} -DMD5=${MD5_PPM_FLOAT_NOSIMD} -DFILE=testoutflt.ppm -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(djpeg-static-float-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_PPM_FLOAT_NOSIMD} -DFILE=testoutflt.ppm -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
endif()
foreach(scale 2_1 15_8 7_4 13_8 3_2 11_8 5_4 9_8 7_8 3_4 5_8 1_2 3_8 1_4 1_8)
string(REGEX REPLACE "_" "/" scalearg ${scale})
add_test(djpeg-static-int-${scale} djpeg-static -dct int -nosmooth -scale ${scalearg} -ppm -outfile testoutint${scale}.ppm ${CMAKE_SOURCE_DIR}/testimages/testorig.jpg)
add_test(djpeg-static-int-${scale}-cmp ${CMAKE_COMMAND} -DMD5=${MD5_PPM_INT_${scale}} -DFILE=testoutint${scale}.ppm -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(djpeg-static-int-${scale} djpeg-static -dct int -nosmooth -scale ${scalearg} -ppm -outfile testoutint${scale}.ppm "${CMAKE_SOURCE_DIR}/testimages/testorig.jpg")
add_test(djpeg-static-int-${scale}-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_PPM_INT_${scale}} -DFILE=testoutint${scale}.ppm -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
endforeach()
add_test(djpeg-static-fast-1_2 djpeg-static -dct fast -scale 1/2 -ppm -outfile testoutfst1_2.ppm ${CMAKE_SOURCE_DIR}/testimages/testorig.jpg)
add_test(djpeg-static-fast-1_2-cmp ${CMAKE_COMMAND} -DMD5=${MD5_PPM_FAST_1_2} -DFILE=testoutfst1_2.ppm -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(djpeg-static-256 djpeg-static -dct int -bmp -colors 256 -outfile testout.bmp ${CMAKE_SOURCE_DIR}/testimages/testorig.jpg)
add_test(djpeg-static-256-cmp ${CMAKE_COMMAND} -DMD5=${MD5_BMP_256} -DFILE=testout.bmp -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(cjpeg-static-prog cjpeg-static -dct int -progressive -outfile testoutp.jpg ${CMAKE_SOURCE_DIR}/testimages/testorig.ppm)
add_test(cjpeg-static-prog-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_PROG} -DFILE=testoutp.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(jpegtran-static-prog jpegtran-static -outfile testoutt.jpg testoutp.jpg)
add_test(jpegtran-static-prog-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_INT} -DFILE=testoutt.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(djpeg-static-fast-1_2 djpeg-static -dct fast -scale 1/2 -ppm -outfile testoutfst1_2.ppm "${CMAKE_SOURCE_DIR}/testimages/testorig.jpg")
add_test(djpeg-static-fast-1_2-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_PPM_FAST_1_2} -DFILE=testoutfst1_2.ppm -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
add_test(djpeg-static-256 djpeg-static -dct int -bmp -colors 256 -outfile testout.bmp "${CMAKE_SOURCE_DIR}/testimages/testorig.jpg")
add_test(djpeg-static-256-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_BMP_256} -DFILE=testout.bmp -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
add_test(cjpeg-static-prog cjpeg-static -dct int -progressive -outfile testoutp.jpg "${CMAKE_SOURCE_DIR}/testimages/testorig.ppm")
add_test(cjpeg-static-prog-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_JPEG_PROG} -DFILE=testoutp.jpg -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
add_test(jpegtran-static-prog jpegtran-static -outfile testoutt.jpg testoutp.jpg")
add_test(jpegtran-static-prog-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_JPEG_INT} -DFILE=testoutt.jpg -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
if(WITH_ARITH_ENC)
add_test(cjpeg-static-ari cjpeg-static -dct int -arithmetic -outfile testoutari.jpg ${CMAKE_SOURCE_DIR}/testimages/testorig.ppm)
add_test(cjpeg-static-ari-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_ARI} -DFILE=testoutari.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake )
add_test(jpegtran-static-toari jpegtran-static -arithmetic -outfile testouta.jpg ${CMAKE_SOURCE_DIR}/testimages/testimgint.jpg)
add_test(jpegtran-static-toari-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_ARI} -DFILE=testouta.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(cjpeg-static-prog-ari cjpeg-static -dct int -progressive -arithmetic -sample 1x1 -outfile testoutpa.jpg ${CMAKE_SOURCE_DIR}/testimages/testorig.ppm)
add_test(cjpeg-static-prog-ari-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_PROG_ARI} -DFILE=testoutpa.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake )
add_test(cjpeg-static-ari cjpeg-static -dct int -arithmetic -outfile testoutari.jpg "${CMAKE_SOURCE_DIR}/testimages/testorig.ppm")
add_test(cjpeg-static-ari-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_JPEG_ARI} -DFILE=testoutari.jpg -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
add_test(jpegtran-static-toari jpegtran-static -arithmetic -outfile testouta.jpg "${CMAKE_SOURCE_DIR}/testimages/testimgint.jpg")
add_test(jpegtran-static-toari-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_JPEG_ARI} -DFILE=testouta.jpg -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
add_test(cjpeg-static-prog-ari cjpeg-static -dct int -progressive -arithmetic -sample 1x1 -outfile testoutpa.jpg "${CMAKE_SOURCE_DIR}/testimages/testorig.ppm")
add_test(cjpeg-static-prog-ari-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_JPEG_PROG_ARI} -DFILE=testoutpa.jpg -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
endif()
if(WITH_ARITH_DEC)
add_test(djpeg-static-ari djpeg-static -dct int -fast -ppm -outfile testoutari.ppm ${CMAKE_SOURCE_DIR}/testimages/testimgari.jpg)
add_test(djpeg-static-ari-cmp ${CMAKE_COMMAND} -DMD5=${MD5_PPM_ARI} -DFILE=testoutari.ppm -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(jpegtran-static-fromari jpegtran-static -outfile testouta.jpg ${CMAKE_SOURCE_DIR}/testimages/testimgari.jpg)
add_test(jpegtran-static-fromari-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_INT} -DFILE=testouta.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(djpeg-static-ari djpeg-static -dct int -fast -ppm -outfile testoutari.ppm "${CMAKE_SOURCE_DIR}/testimages/testimgari.jpg")
add_test(djpeg-static-ari-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_PPM_ARI} -DFILE=testoutari.ppm -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
add_test(jpegtran-static-fromari jpegtran-static -outfile testouta.jpg "${CMAKE_SOURCE_DIR}/testimages/testimgari.jpg")
add_test(jpegtran-static-fromari-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_JPEG_INT} -DFILE=testouta.jpg -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
endif()
add_test(jpegtran-static-crop jpegtran-static -crop 120x90+20+50 -transpose -perfect -outfile testoutcrop.jpg ${CMAKE_SOURCE_DIR}/testimages/testorig.jpg)
add_test(jpegtran-static-crop-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_CROP} -DFILE=testoutcrop.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(jpegtran-static-crop jpegtran-static -crop 120x90+20+50 -transpose -perfect -outfile testoutcrop.jpg "${CMAKE_SOURCE_DIR}/testimages/testorig.jpg")
add_test(jpegtran-static-crop-cmp "${CMAKE_COMMAND}" -DMD5=${MD5_JPEG_CROP} -DFILE=testoutcrop.jpg -P "${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake")
add_custom_target(testclean COMMAND ${CMAKE_COMMAND} -P
${CMAKE_SOURCE_DIR}/cmakescripts/testclean.cmake)
add_custom_target(testclean COMMAND "${CMAKE_COMMAND}" -P
"${CMAKE_SOURCE_DIR}/cmakescripts/testclean.cmake" VERBATIM)
#
@@ -460,7 +460,7 @@ endif()
if(64BIT)
set(INST_PLATFORM "${INST_PLATFORM} 64-bit")
set(INST_NAME ${INST_NAME}64)
set(INST_REG_NAME ${INST_DIR}64)
set(INST_REG_NAME "${INST_DIR}64")
set(INST_DEFS ${INST_DEFS} -DWIN64)
endif()
@@ -474,7 +474,7 @@ else()
set(INST_DEFS ${INST_DEFS} "-DBUILDDIR=")
endif()
STRING(REGEX REPLACE "/" "\\\\" INST_DIR ${CMAKE_INSTALL_PREFIX})
STRING(REGEX REPLACE "/" "\\\\" INST_DIR "${CMAKE_INSTALL_PREFIX}")
configure_file(release/libmozjpeg.nsi.in libmozjpeg.nsi @ONLY)
@@ -493,12 +493,12 @@ install(TARGETS jpeg-static turbojpeg turbojpeg-static rdjpgcom wrjpgcom tjbench
RUNTIME DESTINATION bin
)
install(FILES ${CMAKE_SOURCE_DIR}/README ${CMAKE_SOURCE_DIR}/README-mozilla.txt
${CMAKE_SOURCE_DIR}/example.c ${CMAKE_SOURCE_DIR}/libjpeg.txt
${CMAKE_SOURCE_DIR}/structure.txt ${CMAKE_SOURCE_DIR}/usage.txt
${CMAKE_SOURCE_DIR}/wizard.txt
install(FILES "${CMAKE_SOURCE_DIR}/README" "${CMAKE_SOURCE_DIR}/README-mozilla.txt"
"${CMAKE_SOURCE_DIR}/example.c" "${CMAKE_SOURCE_DIR}/libjpeg.txt"
"${CMAKE_SOURCE_DIR}/structure.txt" "${CMAKE_SOURCE_DIR}/usage.txt"
"${CMAKE_SOURCE_DIR}/wizard.txt"
DESTINATION doc)
install(FILES ${CMAKE_BINARY_DIR}/jconfig.h ${CMAKE_SOURCE_DIR}/jerror.h
${CMAKE_SOURCE_DIR}/jmorecfg.h ${CMAKE_SOURCE_DIR}/jpeglib.h
${CMAKE_SOURCE_DIR}/turbojpeg.h DESTINATION include)
install(FILES "${CMAKE_BINARY_DIR}/jconfig.h" "${CMAKE_SOURCE_DIR}/jerror.h"
"${CMAKE_SOURCE_DIR}/jmorecfg.h" "${CMAKE_SOURCE_DIR}/jpeglib.h"
"${CMAKE_SOURCE_DIR}/turbojpeg.h" DESTINATION include)

View File

@@ -108,7 +108,7 @@ endif
cjpeg_SOURCES = cdjpeg.h cderror.h cdjpeg.c cjpeg.c rdbmp.c rdgif.c \
rdppm.c rdswitch.c rdtarga.c
rdppm.c rdswitch.c rdtarga.c rdjpeg.c
cjpeg_LDADD = libjpeg.la

View File

@@ -144,26 +144,26 @@ AC_DEFUN([AC_CHECK_COMPATIBLE_ARM_ASSEMBLER_IFELSE],[
ac_save_CFLAGS="$CFLAGS"
CFLAGS="$CCASFLAGS -x assembler-with-cpp"
CC="$CCAS"
AC_COMPILE_IFELSE([[
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
.text
.fpu neon
.arch armv7a
.object_arch armv4
.arm
pld [r0]
vmovn.u16 d0, q0]], ac_good_gnu_arm_assembler=yes)
vmovn.u16 d0, q0]])], ac_good_gnu_arm_assembler=yes)
ac_use_gas_preprocessor=no
if test "x$ac_good_gnu_arm_assembler" = "xno" ; then
CC="gas-preprocessor.pl $CCAS"
AC_COMPILE_IFELSE([[
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
.text
.fpu neon
.arch armv7a
.object_arch armv4
.arm
pld [r0]
vmovn.u16 d0, q0]], ac_use_gas_preprocessor=yes)
vmovn.u16 d0, q0]])], ac_use_gas_preprocessor=yes)
fi
CFLAGS="$ac_save_CFLAGS"
CC="$ac_save_CC"
@@ -189,7 +189,7 @@ AC_DEFUN([AC_CHECK_COMPATIBLE_MIPSEL_ASSEMBLER_IFELSE],[
ac_save_CFLAGS="$CFLAGS"
CFLAGS="$CCASFLAGS -mdspr2"
AC_COMPILE_IFELSE([[
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
int main ()
{
@@ -201,7 +201,7 @@ AC_DEFUN([AC_CHECK_COMPATIBLE_MIPSEL_ASSEMBLER_IFELSE],[
);
return c;
}
]], have_mips_dspr2=yes)
]])], have_mips_dspr2=yes)
CFLAGS=$ac_save_CFLAGS
if test "x$have_mips_dspr2" = "xyes" ; then

View File

@@ -3,6 +3,8 @@
*
* Copyright (C) 1994-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* mozjpeg Modifications:
* Copyright (C) 2014, Mozilla Corporation.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains common declarations for the sample applications
@@ -16,6 +18,7 @@
#include "jerror.h" /* get library error codes too */
#include "cderror.h" /* get application-specific error codes */
#define JPEG_RAW_READER 0
/*
* Object interface for cjpeg's source file decoding modules
@@ -35,6 +38,13 @@ struct cjpeg_source_struct {
JSAMPARRAY buffer;
JDIMENSION buffer_height;
#if JPEG_RAW_READER
// For reading JPEG
JSAMPARRAY plane_pointer[4];
#endif
jpeg_saved_marker_ptr marker_list;
};
@@ -94,6 +104,7 @@ typedef struct cdjpeg_progress_mgr * cd_progress_ptr;
#ifdef NEED_SHORT_EXTERNAL_NAMES
#define jinit_read_bmp jIRdBMP
#define jinit_write_bmp jIWrBMP
#define jinit_read_jpeg jIRdJPG
#define jinit_read_gif jIRdGIF
#define jinit_write_gif jIWrGIF
#define jinit_read_ppm jIRdPPM
@@ -122,6 +133,7 @@ EXTERN(djpeg_dest_ptr) jinit_write_bmp JPP((j_decompress_ptr cinfo,
boolean is_os2));
EXTERN(cjpeg_source_ptr) jinit_read_gif JPP((j_compress_ptr cinfo));
EXTERN(djpeg_dest_ptr) jinit_write_gif JPP((j_decompress_ptr cinfo));
EXTERN(cjpeg_source_ptr) jinit_read_jpeg JPP((j_compress_ptr cinfo));
EXTERN(cjpeg_source_ptr) jinit_read_ppm JPP((j_compress_ptr cinfo));
EXTERN(djpeg_dest_ptr) jinit_write_ppm JPP((j_decompress_ptr cinfo));
EXTERN(cjpeg_source_ptr) jinit_read_rle JPP((j_compress_ptr cinfo));

100
cjpeg.c
View File

@@ -80,7 +80,7 @@ static const char * const cdjpeg_message_table[] = {
*/
static boolean is_targa; /* records user -targa switch */
static boolean is_jpeg;
LOCAL(cjpeg_source_ptr)
select_file_type (j_compress_ptr cinfo, FILE * infile)
@@ -121,6 +121,9 @@ select_file_type (j_compress_ptr cinfo, FILE * infile)
case 0x00:
return jinit_read_targa(cinfo);
#endif
case 0xff:
is_jpeg = TRUE;
return jinit_read_jpeg(cinfo);
default:
ERREXIT(cinfo, JERR_UNKNOWN_FORMAT);
break;
@@ -170,6 +173,12 @@ usage (void)
#endif
fprintf(stderr, " -revert Revert to standard defaults (instead of mozjpeg defaults)\n");
fprintf(stderr, " -fastcrush Disable progressive scan optimization\n");
fprintf(stderr, " -multidcscan Use multiple DC scans (may be incompatible with some JPEG decoders)\n");
fprintf(stderr, " -notrellis Disable trellis optimization\n");
fprintf(stderr, " -tune-psnr Tune trellis optimization for PSNR\n");
fprintf(stderr, " -tune-hvs-psnr Tune trellis optimization for PSNR-HVS (default)\n");
fprintf(stderr, " -tune-ssim Tune trellis optimization for SSIM\n");
fprintf(stderr, " -tune-ms-ssim Tune trellis optimization for MS-SSIM\n");
fprintf(stderr, "Switches for advanced users:\n");
#ifdef C_ARITH_CODING_SUPPORTED
fprintf(stderr, " -arithmetic Use arithmetic coding\n");
@@ -302,6 +311,10 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
} else if (keymatch(arg, "fastcrush", 4)) {
cinfo->optimize_scans = FALSE;
} else if (keymatch(arg, "flat", 4)) {
cinfo->use_flat_quant_tbl = TRUE;
jpeg_set_quality(cinfo, 75, TRUE);
} else if (keymatch(arg, "grayscale", 2) || keymatch(arg, "greyscale",2)) {
/* Force a monochrome JPEG file to be generated. */
jpeg_set_colorspace(cinfo, JCS_GRAYSCALE);
@@ -310,6 +323,16 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
/* Force an RGB JPEG file to be generated. */
jpeg_set_colorspace(cinfo, JCS_RGB);
} else if (keymatch(arg, "lambda1", 7)) {
if (++argn >= argc) /* advance to next argument */
usage();
cinfo->lambda_log_scale1 = atof(argv[argn]);
} else if (keymatch(arg, "lambda2", 7)) {
if (++argn >= argc) /* advance to next argument */
usage();
cinfo->lambda_log_scale2 = atof(argv[argn]);
} else if (keymatch(arg, "maxmemory", 3)) {
/* Maximum memory in Kb (or Mb with 'm'). */
long lval;
@@ -323,6 +346,9 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
lval *= 1000L;
cinfo->mem->max_memory_to_use = lval * 1000L;
} else if (keymatch(arg, "multidcscan", 3)) {
cinfo->one_dc_scan = FALSE;
} else if (keymatch(arg, "optimize", 1) || keymatch(arg, "optimise", 1)) {
/* Enable entropy parm optimization. */
#ifdef ENTROPY_OPT_SUPPORTED
@@ -446,6 +472,38 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
/* Input file is Targa format. */
is_targa = TRUE;
} else if (keymatch(arg, "notrellis", 1)) {
/* disable trellis quantization */
cinfo->trellis_quant = FALSE;
} else if (keymatch(arg, "tune-psnr", 6)) {
cinfo->use_flat_quant_tbl = TRUE;
cinfo->lambda_log_scale1 = 9.0;
cinfo->lambda_log_scale2 = 0.0;
cinfo->use_lambda_weight_tbl = FALSE;
jpeg_set_quality(cinfo, 75, TRUE);
} else if (keymatch(arg, "tune-ssim", 6)) {
cinfo->use_flat_quant_tbl = TRUE;
cinfo->lambda_log_scale1 = 12.0;
cinfo->lambda_log_scale2 = 13.5;
cinfo->use_lambda_weight_tbl = FALSE;
jpeg_set_quality(cinfo, 75, TRUE);
} else if (keymatch(arg, "tune-ms-ssim", 6)) {
cinfo->use_flat_quant_tbl = FALSE;
cinfo->lambda_log_scale1 = 14.25;
cinfo->lambda_log_scale2 = 12.75;
cinfo->use_lambda_weight_tbl = TRUE;
jpeg_set_quality(cinfo, 75, TRUE);
} else if (keymatch(arg, "tune-hvs-psnr", 6)) {
cinfo->use_flat_quant_tbl = FALSE;
cinfo->lambda_log_scale1 = 16.0;
cinfo->lambda_log_scale2 = 15.5;
cinfo->use_lambda_weight_tbl = TRUE;
jpeg_set_quality(cinfo, 75, TRUE);
} else {
usage(); /* bogus switch */
}
@@ -609,6 +667,9 @@ main (int argc, char **argv)
(*src_mgr->start_input) (&cinfo, src_mgr);
/* Now that we know input colorspace, fix colorspace-dependent defaults */
#if JPEG_RAW_READER
if (!is_jpeg)
#endif
jpeg_default_colorspace(&cinfo);
/* Adjust default compression parameters by re-parsing the options */
@@ -625,9 +686,46 @@ main (int argc, char **argv)
/* Start compressor */
jpeg_start_compress(&cinfo, TRUE);
/* Copy metadata */
if (is_jpeg) {
jpeg_saved_marker_ptr marker;
/* In the current implementation, we don't actually need to examine the
* option flag here; we just copy everything that got saved.
* But to avoid confusion, we do not output JFIF and Adobe APP14 markers
* if the encoder library already wrote one.
*/
for (marker = src_mgr->marker_list; marker != NULL; marker = marker->next) {
if (cinfo.write_JFIF_header &&
marker->marker == JPEG_APP0 &&
marker->data_length >= 5 &&
GETJOCTET(marker->data[0]) == 0x4A &&
GETJOCTET(marker->data[1]) == 0x46 &&
GETJOCTET(marker->data[2]) == 0x49 &&
GETJOCTET(marker->data[3]) == 0x46 &&
GETJOCTET(marker->data[4]) == 0)
continue; /* reject duplicate JFIF */
if (cinfo.write_Adobe_marker &&
marker->marker == JPEG_APP0+14 &&
marker->data_length >= 5 &&
GETJOCTET(marker->data[0]) == 0x41 &&
GETJOCTET(marker->data[1]) == 0x64 &&
GETJOCTET(marker->data[2]) == 0x6F &&
GETJOCTET(marker->data[3]) == 0x62 &&
GETJOCTET(marker->data[4]) == 0x65)
continue; /* reject duplicate Adobe */
jpeg_write_marker(&cinfo, marker->marker, marker->data, marker->data_length);
}
}
/* Process data */
while (cinfo.next_scanline < cinfo.image_height) {
num_scanlines = (*src_mgr->get_pixel_rows) (&cinfo, src_mgr);
#if JPEG_RAW_READER
if (is_jpeg)
(void) jpeg_write_raw_data(&cinfo, src_mgr->plane_pointer, num_scanlines);
else
#endif
(void) jpeg_write_scanlines(&cinfo, src_mgr->buffer, num_scanlines);
}

View File

@@ -2,10 +2,11 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.56])
AC_INIT([libmozjpeg], [1.0.0])
AC_INIT([libmozjpeg], [2.0pre])
BUILD=`date +%Y%m%d`
AM_INIT_AUTOMAKE([-Wall foreign dist-bzip2])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES(yes)])
AC_PREFIX_DEFAULT(/opt/libmozjpeg)
# Always build with prototypes
@@ -16,8 +17,10 @@ SAVED_CFLAGS=${CFLAGS}
SAVED_CPPFLAGS=${CPPFLAGS}
AC_PROG_CPP
AC_PROG_CC
AM_PROG_CC_C_O
AM_PROG_AS
AC_PROG_INSTALL
AM_PROG_AR
AC_PROG_LIBTOOL
AC_PROG_LN_S
@@ -90,6 +93,7 @@ if test "x${SUNCC}" = "xyes"; then
fi
# Checks for libraries.
AC_CHECK_LIB([m],[pow])
# Checks for header files.
AC_HEADER_STDC
@@ -235,13 +239,13 @@ VERS_1 {
global: *;
};
EOF
AC_LINK_IFELSE(AC_LANG_PROGRAM([], []),
AC_LINK_IFELSE([AC_LANG_SOURCE([AC_LANG_PROGRAM([], [])])],
[VERSION_SCRIPT_FLAG=-Wl,--version-script,;
AC_MSG_RESULT([yes (GNU style)])],
[])
if test "x$VERSION_SCRIPT_FLAG" = "x"; then
LDFLAGS="$SAVED_LDFLAGS -Wl,-M,conftest.map"
AC_LINK_IFELSE(AC_LANG_PROGRAM([], []),
AC_LINK_IFELSE([AC_LANG_SOURCE([AC_LANG_PROGRAM([], [])])],
[VERSION_SCRIPT_FLAG=-Wl,-M,;
AC_MSG_RESULT([yes (Sun style)])],
[])
@@ -262,7 +266,7 @@ AC_SUBST(VERSION_SCRIPT_FLAG)
AC_MSG_CHECKING(for inline)
ljt_cv_inline=""
AC_TRY_COMPILE(, [} __attribute__((always_inline)) int foo() { return 0; }
int bar() { return foo();], ljt_cv_inline="__attribute__((always_inline))",
int bar() { return foo();], ljt_cv_inline="inline __attribute__((always_inline))",
AC_TRY_COMPILE(, [} __inline__ int foo() { return 0; }
int bar() { return foo();], ljt_cv_inline="__inline__",
AC_TRY_COMPILE(, [} __inline int foo() { return 0; }
@@ -270,7 +274,7 @@ int bar() { return foo();], ljt_cv_inline="__inline",
AC_TRY_COMPILE(, [} inline int foo() { return 0; }
int bar() { return foo();], ljt_cv_inline="inline"))))
AC_MSG_RESULT($ljt_cv_inline)
AC_DEFINE_UNQUOTED([INLINE],[$ljt_cv_inline],[How to obtain function inlining.])
AC_DEFINE_UNQUOTED([INLINE],[inline $ljt_cv_inline],[How to obtain function inlining.])
# Arithmetic coding support
AC_MSG_CHECKING([whether to include arithmetic encoding support])

View File

@@ -1,5 +1,5 @@
set(JAR_FILE turbojpeg.jar)
set(MANIFEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/MANIFEST.MF)
set(MANIFEST_FILE "${CMAKE_CURRENT_SOURCE_DIR}/MANIFEST.MF")
set(JAVA_CLASSNAMES org/libjpegturbo/turbojpeg/TJ
org/libjpegturbo/turbojpeg/TJCompressor
@@ -15,7 +15,7 @@ set(JAVA_CLASSNAMES org/libjpegturbo/turbojpeg/TJ
if(MSVC_IDE)
set(OBJDIR "${CMAKE_CURRENT_BINARY_DIR}/$(OutDir)")
else()
set(OBJDIR ${CMAKE_CURRENT_BINARY_DIR})
set(OBJDIR "${CMAKE_CURRENT_BINARY_DIR}")
endif()
set(TURBOJPEG_DLL_NAME "turbojpeg")
@@ -23,33 +23,34 @@ if(MINGW)
set(TURBOJPEG_DLL_NAME "libturbojpeg")
endif()
configure_file(org/libjpegturbo/turbojpeg/TJLoader.java.in
${CMAKE_CURRENT_BINARY_DIR}/org/libjpegturbo/turbojpeg/TJLoader.java)
"${CMAKE_CURRENT_BINARY_DIR}/org/libjpegturbo/turbojpeg/TJLoader.java")
set(JAVA_SOURCES "")
set(JAVA_CLASSES "")
set(JAVA_CLASSES_FULL "")
foreach(class ${JAVA_CLASSNAMES})
set(JAVA_SOURCES ${JAVA_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/${class}.java)
set(JAVA_CLASSES ${JAVA_CLASSES} ${class}.class)
set(JAVA_CLASSES_FULL ${JAVA_CLASSES_FULL} ${OBJDIR}/${class}.class)
list(APPEND JAVA_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/${class}.java")
list(APPEND JAVA_CLASSES "${class}.class")
list(APPEND JAVA_CLASSES_FULL "${OBJDIR}/${class}.class")
endforeach()
set(JAVA_SOURCES ${JAVA_SOURCES}
${CMAKE_CURRENT_BINARY_DIR}/org/libjpegturbo/turbojpeg/TJLoader.java)
set(JAVA_CLASSES ${JAVA_CLASSES}
org/libjpegturbo/turbojpeg/TJLoader.class)
set(JAVA_CLASSES_FULL ${JAVA_CLASSES_FULL}
${OBJDIR}/org/libjpegturbo/turbojpeg/TJLoader.class)
list(APPEND JAVA_SOURCES
"${CMAKE_CURRENT_BINARY_DIR}/org/libjpegturbo/turbojpeg/TJLoader.java")
list(APPEND JAVA_CLASSES org/libjpegturbo/turbojpeg/TJLoader.class)
list(APPEND JAVA_CLASSES_FULL
"${OBJDIR}/org/libjpegturbo/turbojpeg/TJLoader.class")
string(REGEX REPLACE " " ";" JAVACFLAGS "${JAVACFLAGS}")
add_custom_command(OUTPUT ${JAVA_CLASSES_FULL} DEPENDS ${JAVA_SOURCES}
COMMAND ${JAVA_COMPILE} ARGS ${JAVACFLAGS} -d ${OBJDIR} ${JAVA_SOURCES})
COMMAND "${JAVA_COMPILE}" ARGS ${JAVACFLAGS} -d "${OBJDIR}" ${JAVA_SOURCES}
VERBATIM)
add_custom_command(OUTPUT ${JAR_FILE} DEPENDS ${JAVA_CLASSES_FULL}
${MANIFEST_FILE}
COMMAND ${JAVA_ARCHIVE} cfm ${JAR_FILE} ${MANIFEST_FILE} ${JAVA_CLASSES}
WORKING_DIRECTORY ${OBJDIR})
add_custom_command(OUTPUT "${JAR_FILE}" DEPENDS ${JAVA_CLASSES_FULL}
"${MANIFEST_FILE}"
COMMAND "${JAVA_ARCHIVE}" cfm "${JAR_FILE}" "${MANIFEST_FILE}" ${JAVA_CLASSES}
WORKING_DIRECTORY "${OBJDIR}"
VERBATIM)
add_custom_target(java ALL DEPENDS ${JAR_FILE})
add_custom_target(java ALL DEPENDS "${JAR_FILE}")
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${JAR_FILE} DESTINATION classes)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${JAR_FILE}" DESTINATION classes)

View File

@@ -2,6 +2,8 @@
* jccoefct.c
*
* Copyright (C) 1994-1997, Thomas G. Lane.
* mozjpeg Modifications:
* Copyright (C) 2014, Mozilla Corporation.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -13,7 +15,7 @@
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jchuff.h"
/* We use a full-image coefficient buffer when doing Huffman optimization,
* and also for writing multiple-scan JPEG files. In all cases, the DCT
@@ -52,6 +54,10 @@ typedef struct {
/* In multi-pass modes, we need a virtual block array for each component. */
jvirt_barray_ptr whole_image[MAX_COMPONENTS];
/* when using trellis quantization, need to keep a copy of all unquantized coefficients */
jvirt_barray_ptr whole_image_uq[MAX_COMPONENTS];
} my_coef_controller;
typedef my_coef_controller * my_coef_ptr;
@@ -66,6 +72,8 @@ METHODDEF(boolean) compress_first_pass
METHODDEF(boolean) compress_output
JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
#endif
METHODDEF(boolean) compress_trellis_pass
JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
LOCAL(void)
@@ -122,6 +130,12 @@ start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
coef->pub.compress_data = compress_output;
break;
#endif
case JBUF_REQUANT:
if (coef->whole_image[0] == NULL)
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
coef->pub.compress_data = compress_trellis_pass;
break;
default:
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
break;
@@ -177,7 +191,7 @@ compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
(*cinfo->fdct->forward_DCT) (cinfo, compptr,
input_buf[compptr->component_index],
coef->MCU_buffer[blkn],
ypos, xpos, (JDIMENSION) blockcnt);
ypos, xpos, (JDIMENSION) blockcnt, NULL);
if (blockcnt < compptr->MCU_width) {
/* Create some dummy blocks at the right edge of the image. */
jzero_far((void FAR *) coef->MCU_buffer[blkn + blockcnt],
@@ -252,6 +266,7 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
jpeg_component_info *compptr;
JBLOCKARRAY buffer;
JBLOCKROW thisblockrow, lastblockrow;
JBLOCKARRAY buffer_dst;
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
@@ -260,6 +275,12 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
((j_common_ptr) cinfo, coef->whole_image[ci],
coef->iMCU_row_num * compptr->v_samp_factor,
(JDIMENSION) compptr->v_samp_factor, TRUE);
buffer_dst = (*cinfo->mem->access_virt_barray)
((j_common_ptr) cinfo, coef->whole_image_uq[ci],
coef->iMCU_row_num * compptr->v_samp_factor,
(JDIMENSION) compptr->v_samp_factor, TRUE);
/* Count non-dummy DCT block rows in this iMCU row. */
if (coef->iMCU_row_num < last_iMCU_row)
block_rows = compptr->v_samp_factor;
@@ -282,7 +303,7 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
(*cinfo->fdct->forward_DCT) (cinfo, compptr,
input_buf[ci], thisblockrow,
(JDIMENSION) (block_row * DCTSIZE),
(JDIMENSION) 0, blocks_across);
(JDIMENSION) 0, blocks_across, buffer_dst[block_row]);
if (ndummy > 0) {
/* Create dummy blocks at the right edge of the image. */
thisblockrow += blocks_across; /* => first dummy block */
@@ -326,6 +347,101 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
return compress_output(cinfo, input_buf);
}
METHODDEF(boolean)
compress_trellis_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
{
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
JDIMENSION blocks_across, MCUs_across, MCUindex;
int bi, ci, h_samp_factor, block_row, block_rows, ndummy;
JCOEF lastDC;
jpeg_component_info *compptr;
JBLOCKARRAY buffer;
JBLOCKROW thisblockrow, lastblockrow;
JBLOCKARRAY buffer_dst;
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
c_derived_tbl actbl_data;
c_derived_tbl *actbl = &actbl_data;
compptr = cinfo->cur_comp_info[ci];
jpeg_make_c_derived_tbl(cinfo, FALSE, compptr->ac_tbl_no, &actbl);
/* Align the virtual buffer for this component. */
buffer = (*cinfo->mem->access_virt_barray)
((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
coef->iMCU_row_num * compptr->v_samp_factor,
(JDIMENSION) compptr->v_samp_factor, TRUE);
buffer_dst = (*cinfo->mem->access_virt_barray)
((j_common_ptr) cinfo, coef->whole_image_uq[compptr->component_index],
coef->iMCU_row_num * compptr->v_samp_factor,
(JDIMENSION) compptr->v_samp_factor, TRUE);
/* Count non-dummy DCT block rows in this iMCU row. */
if (coef->iMCU_row_num < last_iMCU_row)
block_rows = compptr->v_samp_factor;
else {
/* NB: can't use last_row_height here, since may not be set! */
block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
if (block_rows == 0) block_rows = compptr->v_samp_factor;
}
blocks_across = compptr->width_in_blocks;
h_samp_factor = compptr->h_samp_factor;
/* Count number of dummy blocks to be added at the right margin. */
ndummy = (int) (blocks_across % h_samp_factor);
if (ndummy > 0)
ndummy = h_samp_factor - ndummy;
/* Perform DCT for all non-dummy blocks in this iMCU row. Each call
* on forward_DCT processes a complete horizontal row of DCT blocks.
*/
for (block_row = 0; block_row < block_rows; block_row++) {
thisblockrow = buffer[block_row];
quantize_trellis(cinfo, actbl, thisblockrow, buffer_dst[block_row], blocks_across, cinfo->quant_tbl_ptrs[compptr->quant_tbl_no], cinfo->norm_src[compptr->quant_tbl_no], cinfo->norm_coef[compptr->quant_tbl_no]);
if (ndummy > 0) {
/* Create dummy blocks at the right edge of the image. */
thisblockrow += blocks_across; /* => first dummy block */
jzero_far((void FAR *) thisblockrow, ndummy * SIZEOF(JBLOCK));
lastDC = thisblockrow[-1][0];
for (bi = 0; bi < ndummy; bi++) {
thisblockrow[bi][0] = lastDC;
}
}
}
/* If at end of image, create dummy block rows as needed.
* The tricky part here is that within each MCU, we want the DC values
* of the dummy blocks to match the last real block's DC value.
* This squeezes a few more bytes out of the resulting file...
*/
if (coef->iMCU_row_num == last_iMCU_row) {
blocks_across += ndummy; /* include lower right corner */
MCUs_across = blocks_across / h_samp_factor;
for (block_row = block_rows; block_row < compptr->v_samp_factor;
block_row++) {
thisblockrow = buffer[block_row];
lastblockrow = buffer[block_row-1];
jzero_far((void FAR *) thisblockrow,
(size_t) (blocks_across * SIZEOF(JBLOCK)));
for (MCUindex = 0; MCUindex < MCUs_across; MCUindex++) {
lastDC = lastblockrow[h_samp_factor-1][0];
for (bi = 0; bi < h_samp_factor; bi++) {
thisblockrow[bi][0] = lastDC;
}
thisblockrow += h_samp_factor; /* advance to next MCU in row */
lastblockrow += h_samp_factor;
}
}
}
}
/* NB: compress_output will increment iMCU_row_num if successful.
* A suspension return will result in redoing all the work above next time.
*/
/* Emit data to the entropy encoder, sharing code with subsequent passes */
return compress_output(cinfo, input_buf);
}
/*
* Process some data in subsequent passes of a multi-pass case.
@@ -377,6 +493,7 @@ compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
}
}
}
/* Try to write the MCU. */
if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) {
/* Suspension forced; update state counters and exit */
@@ -429,6 +546,14 @@ jinit_c_coef_controller (j_compress_ptr cinfo, boolean need_full_buffer)
(JDIMENSION) jround_up((long) compptr->height_in_blocks,
(long) compptr->v_samp_factor),
(JDIMENSION) compptr->v_samp_factor);
coef->whole_image_uq[ci] = (*cinfo->mem->request_virt_barray)
((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
(JDIMENSION) jround_up((long) compptr->width_in_blocks,
(long) compptr->h_samp_factor),
(JDIMENSION) jround_up((long) compptr->height_in_blocks,
(long) compptr->v_samp_factor),
(JDIMENSION) compptr->v_samp_factor);
}
#else
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);

View File

@@ -7,6 +7,8 @@
* Copyright (C) 1999-2006, MIYASAKA Masaru.
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
* Copyright (C) 2011 D. R. Commander
* mozjpeg Modifications:
* Copyright (C) 2014, Mozilla Corporation.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains the forward-DCT management logic.
@@ -20,7 +22,8 @@
#include "jpeglib.h"
#include "jdct.h" /* Private declarations for DCT subsystem */
#include "jsimddct.h"
#include <assert.h>
#include <math.h>
/* Private subobject for this module */
@@ -412,7 +415,7 @@ METHODDEF(void)
forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
JDIMENSION start_row, JDIMENSION start_col,
JDIMENSION num_blocks)
JDIMENSION num_blocks, JBLOCKROW dst)
/* This version is used for integer DCT implementations. */
{
/* This routine is heavily used, so it's worth coding it tightly. */
@@ -436,6 +439,36 @@ forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
/* Perform the DCT */
(*do_dct) (workspace);
/* Save unquantized transform coefficients for later trellis quantization */
if (dst) {
int i;
if (cinfo->dct_method == JDCT_IFAST) {
static const INT16 aanscales[DCTSIZE2] = {
/* precomputed values scaled up by 14 bits */
16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270,
21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906,
19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315,
16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552,
8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446,
4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247
};
for (i = 0; i < DCTSIZE2; i++) {
int x = workspace[i];
int s = aanscales[i];
x = (x >= 0) ? (x * 32768 + s) / (2*s) : (x * 32768 - s) / (2*s);
dst[bi][i] = x;
}
} else {
for (i = 0; i < DCTSIZE2; i++) {
dst[bi][i] = workspace[i];
}
}
}
/* Quantize/descale the coefficients, and store into coef_blocks[] */
(*do_quantize) (coef_blocks[bi], divisors, workspace);
}
@@ -502,7 +535,7 @@ METHODDEF(void)
forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
JDIMENSION start_row, JDIMENSION start_col,
JDIMENSION num_blocks)
JDIMENSION num_blocks, JBLOCKROW dst)
/* This version is used for floating-point DCT implementations. */
{
/* This routine is heavily used, so it's worth coding it tightly. */
@@ -527,6 +560,26 @@ forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
/* Perform the DCT */
(*do_dct) (workspace);
/* Save unquantized transform coefficients for later trellis quantization */
/* Currently save as integer values. Could save float values but would require */
/* modifications to memory allocation and trellis quantization */
if (dst) {
int i;
static const double aanscalefactor[DCTSIZE] = {
1.0, 1.387039845, 1.306562965, 1.175875602,
1.0, 0.785694958, 0.541196100, 0.275899379
};
for (i = 0; i < DCTSIZE2; i++) {
float v = workspace[i];
v /= aanscalefactor[i%8];
v /= aanscalefactor[i/8];
int x = (v >= 0.0) ? (int)(v + 0.5) : (int)(v - 0.5);
dst[bi][i] = x;
}
}
/* Quantize/descale the coefficients, and store into coef_blocks[] */
(*do_quantize) (coef_blocks[bi], divisors, workspace);
}
@@ -534,6 +587,290 @@ forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
#endif /* DCT_FLOAT_SUPPORTED */
#include "jchuff.h"
static unsigned char jpeg_nbits_table[65536];
static int jpeg_nbits_table_init = 0;
static const float jpeg_lambda_weights_flat[64] = {
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f
};
static const float jpeg_lambda_weights_csf_luma[64] = {
3.35630f, 3.59892f, 3.20921f, 2.28102f, 1.42378f, 0.88079f, 0.58190f, 0.43454f,
3.59893f, 3.21284f, 2.71282f, 1.98092f, 1.30506f, 0.83852f, 0.56346f, 0.42146f,
3.20921f, 2.71282f, 2.12574f, 1.48616f, 0.99660f, 0.66132f, 0.45610f, 0.34609f,
2.28102f, 1.98092f, 1.48616f, 0.97492f, 0.64622f, 0.43812f, 0.31074f, 0.24072f,
1.42378f, 1.30506f, 0.99660f, 0.64623f, 0.42051f, 0.28446f, 0.20380f, 0.15975f,
0.88079f, 0.83852f, 0.66132f, 0.43812f, 0.28446f, 0.19092f, 0.13635f, 0.10701f,
0.58190f, 0.56346f, 0.45610f, 0.31074f, 0.20380f, 0.13635f, 0.09674f, 0.07558f,
0.43454f, 0.42146f, 0.34609f, 0.24072f, 0.15975f, 0.10701f, 0.07558f, 0.05875f,
};
GLOBAL(void)
quantize_trellis(j_compress_ptr cinfo, c_derived_tbl *actbl, JBLOCKROW coef_blocks, JBLOCKROW src, JDIMENSION num_blocks,
JQUANT_TBL * qtbl, double *norm_src, double *norm_coef)
{
int i, j, k;
float accumulated_zero_dist[DCTSIZE2];
float accumulated_cost[DCTSIZE2];
int run_start[DCTSIZE2];
int bi;
float best_cost;
int last_coeff_idx; /* position of last nonzero coefficient */
float norm = 0.0;
float lambda_base;
float lambda;
const float *lambda_tbl = (cinfo->use_lambda_weight_tbl) ? jpeg_lambda_weights_csf_luma : jpeg_lambda_weights_flat;
int Ss, Se;
float *accumulated_zero_block_cost = NULL;
float *accumulated_block_cost = NULL;
int *block_run_start = NULL;
int *requires_eob = NULL;
int has_eob;
float cost_all_zeros;
float best_cost_skip;
Ss = cinfo->Ss;
Se = cinfo->Se;
if (Ss == 0)
Ss = 1;
if (Se < Ss)
return;
if (cinfo->trellis_eob_opt) {
accumulated_zero_block_cost = (float *)malloc((num_blocks + 1) * SIZEOF(float));
accumulated_block_cost = (float *)malloc((num_blocks + 1) * SIZEOF(float));
block_run_start = (int *)malloc(num_blocks * SIZEOF(int));
requires_eob = (int *)malloc((num_blocks + 1) * SIZEOF(int));
accumulated_zero_block_cost[0] = 0;
accumulated_block_cost[0] = 0;
requires_eob[0] = 0;
}
if(!jpeg_nbits_table_init) {
for(i = 0; i < 65536; i++) {
int nbits = 0, temp = i;
while (temp) {temp >>= 1; nbits++;}
jpeg_nbits_table[i] = nbits;
}
jpeg_nbits_table_init = 1;
}
norm = 0.0;
for (i = 1; i < DCTSIZE2; i++) {
norm += qtbl->quantval[i] * qtbl->quantval[i];
}
norm /= 63.0;
lambda_base = 1.0 / norm;
for (bi = 0; bi < num_blocks; bi++) {
norm = 0.0;
for (i = 1; i < DCTSIZE2; i++) {
norm += src[bi][i] * src[bi][i];
}
norm /= 63.0;
if (cinfo->lambda_log_scale2 > 0.0)
lambda = pow(2.0, cinfo->lambda_log_scale1) * lambda_base / (pow(2.0, cinfo->lambda_log_scale2) + norm);
else
lambda = pow(2.0, cinfo->lambda_log_scale1-12.0) * lambda_base;
accumulated_zero_dist[Ss-1] = 0.0;
accumulated_cost[Ss-1] = 0.0;
for (i = Ss; i <= Se; i++) {
int z = jpeg_natural_order[i];
int sign = src[bi][z] >> 31;
int x = abs(src[bi][z]);
int q = 8 * qtbl->quantval[z];
int candidate[16];
int candidate_bits[16];
float candidate_dist[16];
int num_candidates;
int qval;
accumulated_zero_dist[i] = x * x * lambda * lambda_tbl[z] + accumulated_zero_dist[i-1];
qval = (x + q/2) / q; /* quantized value (round nearest) */
if (qval == 0) {
coef_blocks[bi][z] = 0;
accumulated_cost[i] = 1e38; /* Shouldn't be needed */
continue;
}
num_candidates = jpeg_nbits_table[qval];
for (k = 0; k < num_candidates; k++) {
int delta;
candidate[k] = (k < num_candidates - 1) ? (2 << k) - 1 : qval;
delta = candidate[k] * q - x;
candidate_bits[k] = k+1;
candidate_dist[k] = delta * delta * lambda * lambda_tbl[z];
}
accumulated_cost[i] = 1e38;
for (j = Ss-1; j < i; j++) {
int zz = jpeg_natural_order[j];
if (j != Ss-1 && coef_blocks[bi][zz] == 0)
continue;
int zero_run = i - 1 - j;
if ((zero_run >> 4) && actbl->ehufsi[0xf0] == 0)
continue;
int run_bits = (zero_run >> 4) * actbl->ehufsi[0xf0];
zero_run &= 15;
for (k = 0; k < num_candidates; k++) {
int coef_bits = actbl->ehufsi[16 * zero_run + candidate_bits[k]];
if (coef_bits == 0)
continue;
int rate = coef_bits + candidate_bits[k] + run_bits;
float cost = rate + candidate_dist[k];
cost += accumulated_zero_dist[i-1] - accumulated_zero_dist[j] + accumulated_cost[j];
if (cost < accumulated_cost[i]) {
coef_blocks[bi][z] = (candidate[k] ^ sign) - sign;
accumulated_cost[i] = cost;
run_start[i] = j;
}
}
}
}
last_coeff_idx = Ss-1;
best_cost = accumulated_zero_dist[Se] + actbl->ehufsi[0];
cost_all_zeros = accumulated_zero_dist[Se];
best_cost_skip = cost_all_zeros;
for (i = Ss; i <= Se; i++) {
int z = jpeg_natural_order[i];
if (coef_blocks[bi][z] != 0) {
float cost = accumulated_cost[i] + accumulated_zero_dist[Se] - accumulated_zero_dist[i];
float cost_wo_eob = cost;
if (i < Se)
cost += actbl->ehufsi[0];
if (cost < best_cost) {
best_cost = cost;
last_coeff_idx = i;
best_cost_skip = cost_wo_eob;
}
}
}
has_eob = (last_coeff_idx < Se) + (last_coeff_idx == Ss-1);
/* Zero out coefficients that are part of runs */
i = Se;
while (i >= Ss)
{
while (i > last_coeff_idx) {
int z = jpeg_natural_order[i];
coef_blocks[bi][z] = 0;
i--;
}
last_coeff_idx = run_start[i];
i--;
}
if (cinfo->trellis_eob_opt) {
accumulated_zero_block_cost[bi+1] = accumulated_zero_block_cost[bi];
accumulated_zero_block_cost[bi+1] += cost_all_zeros;
requires_eob[bi+1] = has_eob;
best_cost = 1e38;
if (has_eob != 2) {
for (i = 0; i <= bi; i++) {
int zero_block_run;
int nbits;
float cost;
if (requires_eob[i] == 2)
continue;
cost = best_cost_skip; /* cost of coding a nonzero block */
cost += accumulated_zero_block_cost[bi];
cost -= accumulated_zero_block_cost[i];
cost += accumulated_block_cost[i];
zero_block_run = bi - i + requires_eob[i];
nbits = jpeg_nbits_table[zero_block_run];
cost += actbl->ehufsi[16*nbits] + nbits;
if (cost < best_cost) {
block_run_start[bi] = i;
best_cost = cost;
accumulated_block_cost[bi+1] = cost;
}
}
}
}
}
if (cinfo->trellis_eob_opt) {
int last_block = num_blocks;
best_cost = 1e38;
for (i = 0; i <= num_blocks; i++) {
int zero_block_run;
int nbits;
float cost = 0.0;
if (requires_eob[i] == 2)
continue;
cost += accumulated_zero_block_cost[num_blocks];
cost -= accumulated_zero_block_cost[i];
zero_block_run = num_blocks - i + requires_eob[i];
nbits = jpeg_nbits_table[zero_block_run];
cost += actbl->ehufsi[16*nbits] + nbits;
if (cost < best_cost) {
best_cost = cost;
last_block = i;
}
}
last_block--;
bi = num_blocks - 1;
while (bi >= 0) {
while (bi > last_block) {
for (j = Ss; j <= Se; j++) {
int z = jpeg_natural_order[j];
coef_blocks[bi][z] = 0;
}
bi--;
}
last_block = block_run_start[bi]-1;
bi--;
}
free(accumulated_zero_block_cost);
free(accumulated_block_cost);
free(block_run_start);
free(requires_eob);
}
if (cinfo->trellis_q_opt) {
for (bi = 0; bi < num_blocks; bi++) {
for (i = 1; i < DCTSIZE2; i++) {
norm_src[i] += src[bi][i] * coef_blocks[bi][i];
norm_coef[i] += 8 * coef_blocks[bi][i] * coef_blocks[bi][i];
}
}
}
}
/*
* Initialize FDCT manager.

View File

@@ -2,6 +2,8 @@
* jchuff.h
*
* Copyright (C) 1991-1997, Thomas G. Lane.
* mozjpeg Modifications:
* Copyright (C) 2014, Mozilla Corporation.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -45,3 +47,7 @@ EXTERN(void) jpeg_make_c_derived_tbl
/* Generate an optimal table definition given the specified counts */
EXTERN(void) jpeg_gen_optimal_table
JPP((j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]));
EXTERN(void) quantize_trellis
JPP((j_compress_ptr cinfo, c_derived_tbl *actbl, JBLOCKROW coef_blocks, JBLOCKROW src, JDIMENSION num_blocks,
JQUANT_TBL * qtbl, double *norm_src, double *norm_coef));

View File

@@ -27,7 +27,8 @@
typedef enum {
main_pass, /* input data, also do first output step */
huff_opt_pass, /* Huffman code optimization pass */
output_pass /* data output pass */
output_pass, /* data output pass */
trellis_pass /* trellis quantization pass */
} c_pass_type;
typedef struct {
@@ -41,6 +42,7 @@ typedef struct {
int scan_number; /* current index in scan_info[] */
/* fields for scan optimisation */
int pass_number_scan_opt_base; /* pass number where scan optimization begins */
unsigned char * scan_buffer[64]; /* buffer for a given scan */
unsigned long scan_size[64]; /* size for a given scan */
unsigned long best_cost; /* bit count for best frequency split */
@@ -326,9 +328,21 @@ select_scan_parameters (j_compress_ptr cinfo)
int ci;
#ifdef C_MULTISCAN_FILES_SUPPORTED
if (cinfo->scan_info != NULL) {
/* Prepare for current scan --- the script is already validated */
my_master_ptr master = (my_master_ptr) cinfo->master;
if (master->pass_number < master->pass_number_scan_opt_base) {
cinfo->comps_in_scan = 1;
if (cinfo->use_scans_in_trellis) {
cinfo->cur_comp_info[0] = &cinfo->comp_info[master->pass_number/(4*cinfo->trellis_num_loops)];
cinfo->Ss = (master->pass_number%4 < 2) ? 1 : cinfo->trellis_freq_split+1;
cinfo->Se = (master->pass_number%4 < 2) ? cinfo->trellis_freq_split : DCTSIZE2-1;
} else {
cinfo->cur_comp_info[0] = &cinfo->comp_info[master->pass_number/(2*cinfo->trellis_num_loops)];
cinfo->Ss = 1;
cinfo->Se = DCTSIZE2-1;
}
}
else if (cinfo->scan_info != NULL) {
/* Prepare for current scan --- the script is already validated */
const jpeg_scan_info * scanptr = cinfo->scan_info + master->scan_number;
cinfo->comps_in_scan = scanptr->comps_in_scan;
@@ -467,6 +481,7 @@ METHODDEF(void)
prepare_for_pass (j_compress_ptr cinfo)
{
my_master_ptr master = (my_master_ptr) cinfo->master;
cinfo->trellis_passes = master->pass_number < master->pass_number_scan_opt_base;
switch (master->pass_type) {
case main_pass:
@@ -534,6 +549,22 @@ prepare_for_pass (j_compress_ptr cinfo)
(*cinfo->marker->write_scan_header) (cinfo);
master->pub.call_pass_startup = FALSE;
break;
case trellis_pass:
if (master->pass_number%(cinfo->num_components*(cinfo->use_scans_in_trellis?4:2)) == 1 && cinfo->trellis_q_opt) {
int i, j;
for (i = 0; i < NUM_QUANT_TBLS; i++) {
for (j = 1; j < DCTSIZE2; j++) {
cinfo->norm_src[i][j] = 0.0;
cinfo->norm_coef[i][j] = 0.0;
}
}
}
(*cinfo->entropy->start_pass) (cinfo, TRUE);
(*cinfo->coef->start_pass) (cinfo, JBUF_REQUANT);
master->pub.call_pass_startup = FALSE;
break;
default:
ERREXIT(cinfo, JERR_NOT_COMPILED);
}
@@ -575,6 +606,16 @@ copy_buffer (j_compress_ptr cinfo, int scan_idx)
unsigned long size = master->scan_size[scan_idx];
unsigned char * src = master->scan_buffer[scan_idx];
int i;
if (cinfo->err->trace_level > 0) {
fprintf(stderr, "SCAN ");
for (i = 0; i < cinfo->scan_info[scan_idx].comps_in_scan; i++)
fprintf(stderr, "%s%d", (i==0)?"":",", cinfo->scan_info[scan_idx].component_index[i]);
fprintf(stderr, ": %d %d", cinfo->scan_info[scan_idx].Ss, cinfo->scan_info[scan_idx].Se);
fprintf(stderr, " %d %d", cinfo->scan_info[scan_idx].Ah, cinfo->scan_info[scan_idx].Al);
fprintf(stderr, "\n");
}
while (size >= cinfo->dest->free_in_buffer)
{
@@ -596,8 +637,7 @@ select_scans (j_compress_ptr cinfo, int next_scan_number)
{
my_master_ptr master = (my_master_ptr) cinfo->master;
unsigned long size[8];
int base_scan_idx;
int base_scan_idx = 0;
int luma_freq_split_scan_start = cinfo->num_scans_luma_dc + 3 * cinfo->Al_max_luma + 2;
int chroma_freq_split_scan_start = cinfo->num_scans_luma+cinfo->num_scans_chroma_dc+(6*cinfo->Al_max_chroma+4);
@@ -616,7 +656,7 @@ select_scans (j_compress_ptr cinfo, int next_scan_number)
master->best_Al_luma = Al;
} else {
master->scan_number = luma_freq_split_scan_start - 1;
master->pass_number = 2 * master->scan_number + 1;
master->pass_number = 2 * master->scan_number + 1 + master->pass_number_scan_opt_base;
}
}
@@ -641,7 +681,7 @@ select_scans (j_compress_ptr cinfo, int next_scan_number)
(idx == 3 && master->best_freq_split_idx_luma != 2) ||
(idx == 4 && master->best_freq_split_idx_luma != 4)) {
master->scan_number = cinfo->num_scans_luma - 1;
master->pass_number = 2 * master->scan_number + 1;
master->pass_number = 2 * master->scan_number + 1 + master->pass_number_scan_opt_base;
master->pub.is_last_pass = (master->pass_number == master->total_passes - 1);
}
}
@@ -673,7 +713,7 @@ select_scans (j_compress_ptr cinfo, int next_scan_number)
master->best_Al_chroma = Al;
} else {
master->scan_number = chroma_freq_split_scan_start - 1;
master->pass_number = 2 * master->scan_number + 1;
master->pass_number = 2 * master->scan_number + 1 + master->pass_number_scan_opt_base;
}
}
@@ -701,7 +741,7 @@ select_scans (j_compress_ptr cinfo, int next_scan_number)
(idx == 3 && master->best_freq_split_idx_chroma != 2) ||
(idx == 4 && master->best_freq_split_idx_chroma != 4)) {
master->scan_number = cinfo->num_scans - 1;
master->pass_number = 2 * master->scan_number + 1;
master->pass_number = 2 * master->scan_number + 1 + master->pass_number_scan_opt_base;
master->pub.is_last_pass = (master->pass_number == master->total_passes - 1);
}
}
@@ -714,7 +754,7 @@ select_scans (j_compress_ptr cinfo, int next_scan_number)
copy_buffer(cinfo, 0);
if (cinfo->num_scans > cinfo->num_scans_luma) {
if (cinfo->num_scans > cinfo->num_scans_luma && !cinfo->one_dc_scan) {
base_scan_idx = cinfo->num_scans_luma;
if (master->interleave_chroma_dc)
@@ -792,13 +832,17 @@ finish_pass_master (j_compress_ptr cinfo)
/* next pass is either output of scan 0 (after optimization)
* or output of scan 1 (if no optimization).
*/
if (cinfo->trellis_quant)
master->pass_type = trellis_pass;
else {
master->pass_type = output_pass;
if (! cinfo->optimize_coding)
master->scan_number++;
}
break;
case huff_opt_pass:
/* next pass is always output of current scan */
master->pass_type = output_pass;
master->pass_type = (master->pass_number < master->pass_number_scan_opt_base-1) ? trellis_pass : output_pass;
break;
case output_pass:
/* next pass is either optimization or output of next scan */
@@ -812,6 +856,24 @@ finish_pass_master (j_compress_ptr cinfo)
master->scan_number++;
break;
case trellis_pass:
master->pass_type = (cinfo->optimize_coding || master->pass_number < master->pass_number_scan_opt_base-1) ? huff_opt_pass : output_pass;
if ((master->pass_number+1)%(cinfo->num_components*(cinfo->use_scans_in_trellis?4:2)) == 0 && cinfo->trellis_q_opt) {
int i, j;
for (i = 0; i < NUM_QUANT_TBLS; i++) {
for (j = 1; j < DCTSIZE2; j++) {
if (cinfo->norm_coef[i][j] != 0.0) {
int q = (int)(cinfo->norm_src[i][j] / cinfo->norm_coef[i][j] + 0.5);
if (q > 254) q = 254;
if (q < 1) q = 1;
cinfo->quant_tbl_ptrs[i]->quantval[j] = q;
}
}
}
}
break;
}
master->pass_number++;
@@ -871,6 +933,13 @@ jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only)
else
master->total_passes = cinfo->num_scans;
if (cinfo->trellis_quant) {
if (cinfo->progressive_mode)
master->total_passes += ((cinfo->use_scans_in_trellis) ? 4 : 2) * cinfo->num_components * cinfo->trellis_num_loops;
else
master->total_passes += 1;
}
if (cinfo->optimize_scans) {
int i;
master->best_Al_chroma = 0;
@@ -878,4 +947,9 @@ jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only)
for (i = 0; i < cinfo->num_scans; i++)
master->scan_buffer[i] = NULL;
}
if (cinfo->trellis_quant)
master->pass_number_scan_opt_base = ((cinfo->use_scans_in_trellis) ? 4 : 2) * cinfo->num_components * cinfo->trellis_num_loops;
else
master->pass_number_scan_opt_base = 0;
}

View File

@@ -90,6 +90,16 @@ static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = {
99, 99, 99, 99, 99, 99, 99, 99
};
static const unsigned int flat_quant_tbl[DCTSIZE2] = {
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16
};
#if JPEG_LIB_VERSION >= 70
GLOBAL(void)
@@ -100,11 +110,18 @@ jpeg_default_qtables (j_compress_ptr cinfo, boolean force_baseline)
*/
{
/* Set up two quantization tables using the specified scaling */
if (cinfo->use_flat_quant_tbl) {
jpeg_add_quant_table(cinfo, 0, flat_quant_tbl,
cinfo->q_scale_factor[0], force_baseline);
jpeg_add_quant_table(cinfo, 1, flat_quant_tbl,
cinfo->q_scale_factor[1], force_baseline);
} else {
jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl,
cinfo->q_scale_factor[0], force_baseline);
jpeg_add_quant_table(cinfo, 1, std_chrominance_quant_tbl,
cinfo->q_scale_factor[1], force_baseline);
}
}
#endif
@@ -118,11 +135,18 @@ jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor,
*/
{
/* Set up two quantization tables using the specified scaling */
if (cinfo->use_flat_quant_tbl) {
jpeg_add_quant_table(cinfo, 0, flat_quant_tbl,
scale_factor, force_baseline);
jpeg_add_quant_table(cinfo, 1, flat_quant_tbl,
scale_factor, force_baseline);
} else {
jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl,
scale_factor, force_baseline);
jpeg_add_quant_table(cinfo, 1, std_chrominance_quant_tbl,
scale_factor, force_baseline);
}
}
GLOBAL(int)
@@ -325,6 +349,8 @@ jpeg_set_defaults (j_compress_ptr cinfo)
}
#ifdef C_PROGRESSIVE_SUPPORTED
cinfo->scan_info = NULL;
cinfo->num_scans = 0;
if (!cinfo->use_moz_defaults) {
/* Default is no multiple-scan output */
cinfo->scan_info = NULL;
@@ -399,6 +425,8 @@ jpeg_set_defaults (j_compress_ptr cinfo)
jpeg_default_colorspace(cinfo);
cinfo->one_dc_scan = TRUE;
#ifdef C_PROGRESSIVE_SUPPORTED
if (cinfo->use_moz_defaults) {
cinfo->optimize_scans = TRUE;
@@ -406,6 +434,16 @@ jpeg_set_defaults (j_compress_ptr cinfo)
} else
cinfo->optimize_scans = FALSE;
#endif
cinfo->trellis_quant = cinfo->use_moz_defaults;
cinfo->lambda_log_scale1 = 16.0;
cinfo->lambda_log_scale2 = 15.5;
cinfo->use_lambda_weight_tbl = TRUE;
cinfo->use_scans_in_trellis = FALSE;
cinfo->trellis_freq_split = 8;
cinfo->trellis_num_loops = 1;
cinfo->trellis_q_opt = FALSE;
}
@@ -673,6 +711,9 @@ jpeg_search_progression (j_compress_ptr cinfo)
/* last 4 done conditionally */
/* luma DC by itself */
if (cinfo->one_dc_scan)
scanptr = fill_dc_scans(scanptr, ncomps, 0, 0);
else
scanptr = fill_dc_scans(scanptr, 1, 0, 0);
scanptr = fill_a_scan(scanptr, 0, 1, 8, 0, 0);
@@ -761,7 +802,7 @@ jpeg_simple_progression (j_compress_ptr cinfo)
nscans = 10;
} else {
/* All-purpose script for other color spaces. */
if (cinfo->use_moz_defaults) {
if (cinfo->use_moz_defaults == TRUE) {
if (ncomps > MAX_COMPS_IN_SCAN)
nscans = 5 * ncomps; /* 2 DC + 4 AC scans per component */
else
@@ -793,11 +834,15 @@ jpeg_simple_progression (j_compress_ptr cinfo)
if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) {
/* Custom script for YCbCr color images. */
if (cinfo->use_moz_defaults) {
if (cinfo->use_moz_defaults == TRUE) {
/* scan defined in jpeg_scan_rgb.txt in jpgcrush */
/* Initial DC scan */
if (cinfo->one_dc_scan)
scanptr = fill_dc_scans(scanptr, ncomps, 0, 0);
else {
scanptr = fill_dc_scans(scanptr, 1, 0, 0);
scanptr = fill_a_scan_pair(scanptr, 1, 0, 0, 0, 0);
}
/* Low frequency AC scans */
scanptr = fill_a_scan(scanptr, 0, 1, 8, 0, 2);
scanptr = fill_a_scan(scanptr, 1, 1, 8, 0, 0);
@@ -832,7 +877,7 @@ jpeg_simple_progression (j_compress_ptr cinfo)
}
} else {
/* All-purpose script for other color spaces. */
if (cinfo->use_moz_defaults) {
if (cinfo->use_moz_defaults == TRUE) {
/* scan defined in jpeg_scan_bw.txt in jpgcrush */
/* DC component, no successive approximation */
scanptr = fill_dc_scans(scanptr, ncomps, 0, 0);

View File

@@ -2,6 +2,8 @@
* jcphuff.c
*
* Copyright (C) 1995-1997, Thomas G. Lane.
* mozjpeg Modifications:
* Copyright (C) 2014, Mozilla Corporation.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -167,6 +169,14 @@ start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
257 * SIZEOF(long));
MEMZERO(entropy->count_ptrs[tbl], 257 * SIZEOF(long));
if (cinfo->trellis_passes) {
/* When generating tables for trellis passes, make sure that all */
/* codewords have an assigned length */
int i, j;
for (i = 0; i < 16; i++)
for (j = 0; j < 12; j++)
entropy->count_ptrs[tbl][16*i+j] = 1;
}
} else {
/* Compute derived values for Huffman table */
/* We may do this more than once for a table, but it's not expensive */
@@ -468,6 +478,8 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
int Se = cinfo->Se;
int Al = cinfo->Al;
JBLOCKROW block;
int deadzone = (1 << Al) - 1;
int sign;
entropy->next_output_byte = cinfo->dest->next_output_byte;
entropy->free_in_buffer = cinfo->dest->free_in_buffer;
@@ -485,29 +497,24 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
r = 0; /* r = run length of zeros */
for (k = cinfo->Ss; k <= Se; k++) {
if ((temp = (*block)[jpeg_natural_order[k]]) == 0) {
temp = (*block)[jpeg_natural_order[k]];
if ((unsigned)(temp + deadzone) <= 2*deadzone) {
r++;
continue;
}
/* We must apply the point transform by Al. For AC coefficients this
* is an integer division with rounding towards 0. To do this portably
* in C, we shift after obtaining the absolute value; so the code is
* is an integer division with rounding towards 0. The code is
* interwoven with finding the abs value (temp) and output bits (temp2).
*/
if (temp < 0) {
temp = -temp; /* temp is abs value of input */
temp >>= Al; /* apply the point transform */
/* For a negative coef, want temp2 = bitwise complement of abs(coef) */
temp2 = ~temp;
} else {
temp >>= Al; /* apply the point transform */
temp2 = temp;
}
/* Watch out for case that nonzero coef is zero after point transform */
if (temp == 0) {
r++;
continue;
}
#ifdef RIGHT_SHIFT_IS_UNSIGNED
sign = (temp < 0) ? ~0 : 0;
#else
sign = temp >> (8*sizeof(temp)-1);
#endif
temp += sign;
temp = (temp ^ sign) >> Al;
temp2 = temp ^ sign;
/* Emit any pending EOBRUN */
if (entropy->EOBRUN > 0)

View File

@@ -89,6 +89,8 @@ jpeg_copy_critical_parameters (j_decompress_ptr srcinfo,
#endif
/* Initialize all parameters to default values */
jpeg_set_defaults(dstinfo);
dstinfo->trellis_quant = FALSE;
/* jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB.
* Fix it to get the right header markers for the image colorspace.
*/

View File

@@ -3,6 +3,8 @@
*
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 1997-2009 by Guido Vollbeding.
* mozjpeg Modifications:
* Copyright (C) 2014, Mozilla Corporation.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -19,7 +21,9 @@ typedef enum { /* Operating modes for buffer controllers */
/* Remaining modes require a full-image buffer to have been created */
JBUF_SAVE_SOURCE, /* Run source subobject only, save output */
JBUF_CRANK_DEST, /* Run dest subobject only, using saved data */
JBUF_SAVE_AND_PASS /* Run both subobjects, save output */
JBUF_SAVE_AND_PASS, /* Run both subobjects, save output */
JBUF_REQUANT /* Requantize */
} J_BUF_MODE;
/* Values of global_state field (jdapi.c has some dependencies on ordering!) */
@@ -107,7 +111,7 @@ struct jpeg_forward_dct {
jpeg_component_info * compptr,
JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
JDIMENSION start_row, JDIMENSION start_col,
JDIMENSION num_blocks));
JDIMENSION num_blocks, JBLOCKROW dst));
};
/* Entropy encoding */

View File

@@ -376,8 +376,22 @@ struct jpeg_compress_struct {
int smoothing_factor; /* 1..100, or 0 for no input smoothing */
J_DCT_METHOD dct_method; /* DCT algorithm selector */
boolean use_moz_defaults; /* TRUE if using Mozilla defaults */
boolean use_moz_defaults; /* TRUE=use Mozilla defaults */
boolean optimize_scans; /* TRUE=optimize progressive coding scans */
boolean one_dc_scan; /* TRUE=use a single DC scan interleaving all components */
boolean trellis_quant; /* TRUE=use trellis quantization */
boolean trellis_eob_opt; /* TRUE=optimize for sequences of EOB */
boolean use_flat_quant_tbl; /* TRUE=use flat quantization table */
boolean use_lambda_weight_tbl; /* TRUE=use lambda weighting table */
boolean use_scans_in_trellis; /* TRUE=use scans in trellis optimization */
boolean trellis_passes; /* TRUE=currently doing trellis-related passes */
boolean trellis_q_opt; /* TRUE=optimize quant table in trellis loop */
double norm_src[NUM_QUANT_TBLS][DCTSIZE2];
double norm_coef[NUM_QUANT_TBLS][DCTSIZE2];
int trellis_freq_split; /* splitting point for frequency in trellis quantization */
int trellis_num_loops; /* number of trellis loops */
int num_scans_luma; /* # of entries in scan_info array pertaining to luma (used when optimize_scans is TRUE */
int num_scans_luma_dc;
@@ -387,6 +401,9 @@ struct jpeg_compress_struct {
int Al_max_luma; /* maximum value of Al tested when optimizing scans (luma) */
int Al_max_chroma; /* maximum value of Al tested when optimizing scans (chroma) */
float lambda_log_scale1;
float lambda_log_scale2;
/* The restart interval can be specified in absolute MCUs by setting
* restart_interval, or in MCU rows by setting restart_in_rows
* (in which case the correct restart_interval will be figured

View File

@@ -48,14 +48,20 @@ int main(int argc, char *argv[]) {
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE *jpg_fd;
int width;
int height;
int luma_width;
int luma_height;
int chroma_width;
int chroma_height;
int frame_width;
int frame_height;
int yuv_size;
JSAMPLE *image_buffer;
JSAMPROW yrow_pointer[16];
JSAMPROW cbrow_pointer[8];
JSAMPROW crrow_pointer[8];
JSAMPROW *plane_pointer[3];
unsigned char *yuv_buffer;
int x;
int y;
FILE *yuv_fd;
@@ -90,32 +96,54 @@ int main(int argc, char *argv[]) {
jpeg_start_decompress(&cinfo);
width = cinfo.output_width;
height = cinfo.output_height;
/* Right now we only support dimensions that are multiples of 16. */
if ((width % 16) != 0 || (height % 16) != 0) {
fprintf(stderr, "Image dimensions must be multiples of 16!\n");
return 1;
}
luma_width = cinfo.output_width;
luma_height = cinfo.output_height;
yuv_size = (width * height) + (((width >> 1) * (height >> 1)) * 2);
image_buffer = malloc(yuv_size);
chroma_width = (luma_width + 1) >> 1;
chroma_height = (luma_height + 1) >> 1;
yuv_size = luma_width*luma_height + 2*chroma_width*chroma_height;
yuv_buffer = malloc(yuv_size);
frame_width = (cinfo.output_width + (16 - 1)) & ~(16 - 1);
frame_height = (cinfo.output_height + (16 - 1)) & ~(16 - 1);
image_buffer = malloc(frame_width*16 + 2*(frame_width/2)*8);
plane_pointer[0] = yrow_pointer;
plane_pointer[1] = cbrow_pointer;
plane_pointer[2] = crrow_pointer;
while (cinfo.output_scanline < cinfo.output_height) {
for (y = 0; y < 16; y++) {
yrow_pointer[y] = image_buffer + cinfo.image_width * (cinfo.output_scanline + y);
yrow_pointer[y] = &image_buffer[frame_width*y];
}
for (y = 0; y < 8; y++) {
cbrow_pointer[y] = image_buffer + width * height +
((width + 1) >> 1) * ((cinfo.output_scanline >> 1) + y);
crrow_pointer[y] = image_buffer + width * height +
((width + 1) >> 1) * ((height + 1) >> 1) +
((width + 1) >> 1) * ((cinfo.output_scanline >> 1) + y);
cbrow_pointer[y] = &image_buffer[frame_width*16 + (frame_width/2)*y];
crrow_pointer[y] = &image_buffer[frame_width*16 + (frame_width/2)*(8 + y)];
}
while (cinfo.output_scanline < cinfo.output_height) {
int luma_scanline;
int chroma_scanline;
luma_scanline = cinfo.output_scanline;
chroma_scanline = (luma_scanline + 1) >> 1;
jpeg_read_raw_data(&cinfo, plane_pointer, 16);
for (y = 0; y < 16 && luma_scanline + y < luma_height; y++) {
for (x = 0; x < luma_width; x++) {
yuv_buffer[luma_width*(luma_scanline + y) + x] = yrow_pointer[y][x];
}
}
for (y = 0; y < 8 && chroma_scanline + y < chroma_height; y++) {
for (x = 0; x < chroma_width; x++) {
yuv_buffer[luma_width*luma_height +
chroma_width*(chroma_scanline + y) + x] = cbrow_pointer[y][x];
yuv_buffer[luma_width*luma_height + chroma_width*chroma_height +
chroma_width*(chroma_scanline + y) + x] = crrow_pointer[y][x];
}
}
}
jpeg_finish_decompress(&cinfo);
@@ -124,15 +152,19 @@ int main(int argc, char *argv[]) {
fclose(jpg_fd);
free(image_buffer);
yuv_fd = fopen(yuv_path, "wb");
if (!yuv_fd) {
fprintf(stderr, "Invalid path to YUV file!");
return 1;
}
if (fwrite(image_buffer, yuv_size, 1, yuv_fd)!=1) {
if (fwrite(yuv_buffer, yuv_size, 1, yuv_fd) != 1) {
fprintf(stderr, "Error writing yuv file\n");
}
fclose(yuv_fd);
free(yuv_buffer);
return 0;
}

View File

@@ -5,6 +5,8 @@
* Copyright (C) 1991-2012, Thomas G. Lane, Guido Vollbeding.
* Modifications:
* Copyright (C) 2010, 2012-2013, D. R. Commander.
* mozjpeg Modifications:
* Copyright (C) 2014, Mozilla Corporation.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains software version identification.
@@ -29,4 +31,6 @@
"Copyright (C) 1999-2006 MIYASAKA Masaru\n" \
"Copyright (C) 2009 Pierre Ossman for Cendio AB\n" \
"Copyright (C) 2009-2013 D. R. Commander\n" \
"Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies)"
"Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies)\n" \
"Copyright (C) 2014 Mozilla Corporation\n"

160
rdjpeg.c Normal file
View File

@@ -0,0 +1,160 @@
/*
* rdjpeg.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* mozjpeg Modifications:
* Copyright (C) 2014, Mozilla Corporation.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
*/
#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
#if JPEG_RAW_READER
#define NUM_ROWS 32
#endif
/* Private version of data source object */
typedef struct _jpeg_source_struct * jpeg_source_ptr;
typedef struct _jpeg_source_struct {
struct cjpeg_source_struct pub; /* public fields */
j_compress_ptr cinfo; /* back link saves passing separate parm */
struct jpeg_decompress_struct dinfo;
struct jpeg_error_mgr jerr;
} jpeg_source_struct;
METHODDEF(JDIMENSION)
get_rows (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
{
jpeg_source_ptr source = (jpeg_source_ptr) sinfo;
#if !JPEG_RAW_READER
return jpeg_read_scanlines(&source->dinfo, source->pub.buffer, source->pub.buffer_height);
#else
jpeg_read_raw_data(&source->dinfo, source->pub.plane_pointer, 8*cinfo->max_v_samp_factor);
return 8*cinfo->max_v_samp_factor;
#endif
}
/*
* Read the file header; return image size and component count.
*/
METHODDEF(void)
start_input_jpeg (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
{
#if JPEG_RAW_READER
int i;
#endif
int m;
jpeg_source_ptr source = (jpeg_source_ptr) sinfo;
source->dinfo.err = jpeg_std_error(&source->jerr);
jpeg_create_decompress(&source->dinfo);
jpeg_stdio_src(&source->dinfo, source->pub.input_file);
jpeg_save_markers(&source->dinfo, JPEG_COM, 0xFFFF);
for (m = 0; m < 16; m++)
jpeg_save_markers(&source->dinfo, JPEG_APP0 + m, 0xFFFF);
jpeg_read_header(&source->dinfo, TRUE);
source->pub.marker_list = source->dinfo.marker_list;
#if !JPEG_RAW_READER
source->dinfo.raw_data_out = FALSE;
jpeg_start_decompress(&source->dinfo);
cinfo->in_color_space = source->dinfo.out_color_space;
cinfo->input_components = source->dinfo.output_components;
cinfo->data_precision = source->dinfo.data_precision;
cinfo->image_width = source->dinfo.image_width;
cinfo->image_height = source->dinfo.image_height;
cinfo->raw_data_in = FALSE;
source->pub.buffer = (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE,
(JDIMENSION) (cinfo->image_width * cinfo->input_components), (JDIMENSION) 1);
source->pub.buffer_height = 1;
#else
source->dinfo.raw_data_out = TRUE;
source->dinfo.do_fancy_upsampling = FALSE;
jpeg_start_decompress(&source->dinfo);
cinfo->in_color_space = source->dinfo.out_color_space;
cinfo->input_components = source->dinfo.output_components;
cinfo->data_precision = source->dinfo.data_precision;
cinfo->image_width = source->dinfo.image_width;
cinfo->image_height = source->dinfo.image_height;
jpeg_set_colorspace(cinfo, source->dinfo.jpeg_color_space);
cinfo->max_v_samp_factor = source->dinfo.max_v_samp_factor;
cinfo->max_h_samp_factor = source->dinfo.max_h_samp_factor;
cinfo->raw_data_in = TRUE;
#if JPEG_LIB_VERSION >= 70
cinfo->do_fancy_upsampling = FALSE;
#endif
for (i = 0; i < cinfo->input_components; i++) {
cinfo->comp_info[i].h_samp_factor = source->dinfo.comp_info[i].h_samp_factor;
cinfo->comp_info[i].v_samp_factor = source->dinfo.comp_info[i].v_samp_factor;
source->pub.plane_pointer[i] = (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE,
(JDIMENSION) cinfo->image_width, (JDIMENSION) NUM_ROWS);
}
#endif
source->pub.get_pixel_rows = get_rows;
}
/*
* Finish up at the end of the file.
*/
METHODDEF(void)
finish_input_jpeg (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
{
jpeg_source_ptr source = (jpeg_source_ptr) sinfo;
jpeg_finish_decompress(&source->dinfo);
jpeg_destroy_decompress(&source->dinfo);
}
/*
* The module selection routine for JPEG format input.
*/
GLOBAL(cjpeg_source_ptr)
jinit_read_jpeg (j_compress_ptr cinfo)
{
jpeg_source_ptr source;
/* Create module interface object */
source = (jpeg_source_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(jpeg_source_struct));
source->cinfo = cinfo; /* make back link for subroutines */
/* Fill in method ptrs, except get_pixel_rows which start_input sets */
source->pub.start_input = start_input_jpeg;
source->pub.finish_input = finish_input_jpeg;
return (cjpeg_source_ptr) source;
}

View File

@@ -300,15 +300,32 @@ static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = {
99, 99, 99, 99, 99, 99, 99, 99
};
static const unsigned int flat_quant_tbl[DCTSIZE2] = {
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16
};
LOCAL(void)
jpeg_default_qtables (j_compress_ptr cinfo, boolean force_baseline)
{
if (cinfo->use_flat_quant_tbl) {
jpeg_add_quant_table(cinfo, 0, flat_quant_tbl,
q_scale_factor[0], force_baseline);
jpeg_add_quant_table(cinfo, 1, flat_quant_tbl,
q_scale_factor[1], force_baseline);
} else {
jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl,
q_scale_factor[0], force_baseline);
jpeg_add_quant_table(cinfo, 1, std_chrominance_quant_tbl,
q_scale_factor[1], force_baseline);
}
}
#endif

View File

@@ -16,7 +16,7 @@ if(MSVC)
endif()
foreach(src ${JPEG_SOURCES})
set(JPEG_SRCS ${JPEG_SRCS} ${CMAKE_SOURCE_DIR}/${src})
list(APPEND JPEG_SRCS "${CMAKE_SOURCE_DIR}/${src}")
endforeach()
if(WITH_SIMD)
@@ -26,10 +26,10 @@ endif()
if(WITH_MEM_SRCDST AND NOT WITH_JPEG8)
add_library(jpeg SHARED ${JPEG_SRCS} ${SIMD_OBJS}
${CMAKE_SOURCE_DIR}/win/jpeg${DLL_VERSION}-memsrcdst.def)
"${CMAKE_SOURCE_DIR}/win/jpeg${DLL_VERSION}-memsrcdst.def")
else()
add_library(jpeg SHARED ${JPEG_SRCS} ${SIMD_OBJS}
${CMAKE_SOURCE_DIR}/win/jpeg${DLL_VERSION}.def)
"${CMAKE_SOURCE_DIR}/win/jpeg${DLL_VERSION}.def")
endif()
set_target_properties(jpeg PROPERTIES SOVERSION ${DLL_VERSION}
VERSION ${FULLVERSION})
@@ -43,7 +43,7 @@ if(WITH_SIMD)
endif()
add_executable(cjpeg ../cjpeg.c ../cdjpeg.c ../rdbmp.c ../rdgif.c ../rdppm.c
../rdswitch.c ../rdtarga.c)
../rdswitch.c ../rdtarga.c ../rdjpeg.c)
set_property(TARGET cjpeg PROPERTY COMPILE_FLAGS
"-DBMP_SUPPORTED -DGIF_SUPPORTED -DPPM_SUPPORTED -DTARGA_SUPPORTED -DUSE_SETMODE")
target_link_libraries(cjpeg jpeg)

View File

@@ -3,11 +3,11 @@ if(NOT DEFINED NASM)
endif()
if(SIMD_X86_64)
set(NAFLAGS -fwin64 -DWIN64 -D__x86_64__ -I${CMAKE_SOURCE_DIR}/win/
-I${CMAKE_CURRENT_SOURCE_DIR}/)
set(NAFLAGS -fwin64 -DWIN64 -D__x86_64__ "-I${CMAKE_SOURCE_DIR}/win/"
"-I${CMAKE_CURRENT_SOURCE_DIR}/")
else()
set(NAFLAGS -fwin32 -DWIN32 -I${CMAKE_SOURCE_DIR}/win/
-I${CMAKE_CURRENT_SOURCE_DIR}/)
set(NAFLAGS -fwin32 -DWIN32 "-I${CMAKE_SOURCE_DIR}/win/"
"-I${CMAKE_CURRENT_SOURCE_DIR}/")
endif()
# This only works if building from the command line. There is currently no way
@@ -34,34 +34,35 @@ endif()
if(MSVC_IDE)
set(OBJDIR "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
else()
set(OBJDIR ${CMAKE_CURRENT_BINARY_DIR})
set(OBJDIR "${CMAKE_CURRENT_BINARY_DIR}")
endif()
file(GLOB INC_FILES *.inc)
foreach(file ${SIMD_BASENAMES})
set(DEPFILE "")
set(SIMD_SRC ${CMAKE_CURRENT_SOURCE_DIR}/${file}.asm)
if(${file} MATCHES col)
set(DEPFILE ${file})
string(REGEX REPLACE "col" "clr" DEPFILE ${DEPFILE})
set(DEPFILE ${CMAKE_CURRENT_SOURCE_DIR}/${DEPFILE}.asm)
set(SIMD_SRC "${CMAKE_CURRENT_SOURCE_DIR}/${file}.asm")
if("${file}" MATCHES col)
set(DEPFILE "${file}")
string(REGEX REPLACE "col" "clr" DEPFILE "${DEPFILE}")
set(DEPFILE "${CMAKE_CURRENT_SOURCE_DIR}/${DEPFILE}.asm")
endif()
if(${file} MATCHES mer)
set(DEPFILE ${file})
string(REGEX REPLACE "mer" "mrg" DEPFILE ${DEPFILE})
set(DEPFILE ${CMAKE_CURRENT_SOURCE_DIR}/${DEPFILE}.asm)
if("${file}" MATCHES mer)
set(DEPFILE "${file}")
string(REGEX REPLACE "mer" "mrg" DEPFILE "${DEPFILE}")
set(DEPFILE "${CMAKE_CURRENT_SOURCE_DIR}/${DEPFILE}.asm")
endif()
if(${file} MATCHES gra)
set(DEPFILE ${file})
string(REGEX REPLACE "gra" "gry" DEPFILE ${DEPFILE})
set(DEPFILE ${CMAKE_CURRENT_SOURCE_DIR}/${DEPFILE}.asm)
if("${file}" MATCHES gra)
set(DEPFILE "${file}")
string(REGEX REPLACE "gra" "gry" DEPFILE "${DEPFILE}")
set(DEPFILE "${CMAKE_CURRENT_SOURCE_DIR}/${DEPFILE}.asm")
endif()
set(SIMD_OBJ ${OBJDIR}/${file}.obj)
add_custom_command(OUTPUT ${SIMD_OBJ}
DEPENDS ${SIMD_SRC} ${DEPFILE} ${INC_FILES}
COMMAND ${NASM} ${NAFLAGS} ${SIMD_SRC} -o${SIMD_OBJ})
set(SIMD_OBJS ${SIMD_OBJS} ${SIMD_OBJ})
set(SIMD_OBJ "${OBJDIR}/${file}.obj")
add_custom_command(OUTPUT "${SIMD_OBJ}"
DEPENDS "${SIMD_SRC}" "${DEPFILE}" ${INC_FILES}
COMMAND "${NASM}" ${NAFLAGS} "${SIMD_SRC}" "-o${SIMD_OBJ}"
VERBATIM)
list(APPEND SIMD_OBJS "${SIMD_OBJ}")
endforeach()
set(SIMD_OBJS ${SIMD_OBJS} PARENT_SCOPE)

View File

@@ -67,7 +67,7 @@ endif
AM_CPPFLAGS = -I$(top_srcdir)
.asm.lo:
$(LIBTOOL) --mode=compile --tag NASM $(srcdir)/nasm_lt.sh $(NASM) $(NAFLAGS) -I$(srcdir) -I. $< -o $@
$(AM_V_GEN) $(LIBTOOL) $(AM_V_lt) --mode=compile $(srcdir)/nasm_lt.sh $(AM_V_lt) $(NASM) $(NAFLAGS) -I$(srcdir) -I. $< -o $@
jsimdcfg.inc: $(srcdir)/jsimdcfg.inc.h ../jpeglib.h ../jconfig.h ../jmorecfg.h
$(CPP) -I$(top_builddir) -I$(top_builddir)/simd $(srcdir)/jsimdcfg.inc.h | $(EGREP) "^[\;%]|^\ %" | sed 's%_cpp_protection_%%' | sed 's@% define@%define@g' > $@
$(AM_V_GEN) $(CPP) -I$(top_builddir) -I$(top_builddir)/simd $(srcdir)/jsimdcfg.inc.h | $(EGREP) "^[\;%]|^\ %" | sed 's%_cpp_protection_%%' | sed 's@% define@%define@g' > $@

View File

@@ -5,6 +5,9 @@ o_opt=no
pic=no
while [ $# -gt 0 ]; do
case "$1" in
--silent)
exec > /dev/null
;;
-DPIC|-fPIC|-fpic|-Kpic|-KPIC)
if [ "$pic" != "yes" ] ; then
command="$command -DPIC"

View File

@@ -256,7 +256,7 @@ int decomptest(unsigned char *srcbuf, unsigned char **jpegbuf,
}
void dotestyuv(unsigned char *srcbuf, int w, int h, int subsamp,
int dotestyuv(unsigned char *srcbuf, int w, int h, int subsamp,
char *filename)
{
char tempstr[1024], tempstr2[80];
@@ -328,11 +328,11 @@ void dotestyuv(unsigned char *srcbuf, int w, int h, int subsamp,
if(file) {fclose(file); file=NULL;}
if(dstbuf) {free(dstbuf); dstbuf=NULL;}
if(handle) {tjDestroy(handle); handle=NULL;}
return;
return retval;
}
void dotest(unsigned char *srcbuf, int w, int h, int subsamp, int jpegqual,
int dotest(unsigned char *srcbuf, int w, int h, int subsamp, int jpegqual,
char *filename)
{
char tempstr[1024], tempstr2[80];
@@ -345,7 +345,7 @@ void dotest(unsigned char *srcbuf, int w, int h, int subsamp, int jpegqual,
int ntilesw=1, ntilesh=1, pitch=w*ps;
const char *pfStr=(yuv==YUVCOMPRESS)? "YUV":pixFormatStr[pf];
if(yuv==YUVENCODE) {dotestyuv(srcbuf, w, h, subsamp, filename); return;}
if(yuv==YUVENCODE) {dotestyuv(srcbuf, w, h, subsamp, filename); return retval;}
if((tmpbuf=(unsigned char *)malloc(pitch*h)) == NULL)
_throwunix("allocating temporary image buffer");
@@ -498,11 +498,11 @@ void dotest(unsigned char *srcbuf, int w, int h, int subsamp, int jpegqual,
if(jpegsize) {free(jpegsize); jpegsize=NULL;}
if(tmpbuf) {free(tmpbuf); tmpbuf=NULL;}
if(handle) {tjDestroy(handle); handle=NULL;}
return;
return retval;
}
void dodecomptest(char *filename)
int dodecomptest(char *filename)
{
FILE *file=NULL; tjhandle handle=NULL;
unsigned char **jpegbuf=NULL, *srcbuf=NULL;
@@ -706,7 +706,7 @@ void dodecomptest(char *filename)
if(srcbuf) {free(srcbuf); srcbuf=NULL;}
if(t) {free(t); t=NULL;}
if(handle) {tjDestroy(handle); handle=NULL;}
return;
return retval;
}

View File

@@ -1171,6 +1171,7 @@ transpose_critical_parameters (j_compress_ptr dstinfo)
}
#if JPEG_LIB_VERSION >= 70
/* Adjust Exif image parameters.
*
* We try to adjust the Tags ExifImageWidth and ExifImageHeight if possible.
@@ -1325,6 +1326,7 @@ adjust_exif_parameters (JOCTET FAR * data, unsigned int length,
offset += 12;
} while (--number_of_tags);
}
#endif
/* Adjust output image parameters as needed.

View File

@@ -123,7 +123,10 @@ static const tjscalingfactor sf[NUMSF]={
j_compress_ptr cinfo=NULL; j_decompress_ptr dinfo=NULL; \
if(!this) {snprintf(errStr, JMSG_LENGTH_MAX, "Invalid handle"); \
return -1;} \
cinfo=&this->cinfo; dinfo=&this->dinfo;
cinfo=&this->cinfo; \
(void)cinfo; \
dinfo=&this->dinfo; \
(void)dinfo
static int getPixelFormat(int pixelSize, int flags)
{
@@ -612,7 +615,7 @@ DLLEXPORT int DLLCALL tjCompress2(tjhandle handle, unsigned char *srcBuf,
unsigned char *rgbBuf=NULL;
#endif
getinstance(handle)
getinstance(handle);
if((this->init&COMPRESS)==0)
_throw("tjCompress2(): Instance has not been initialized for compression");
@@ -878,7 +881,7 @@ DLLEXPORT int DLLCALL tjCompressFromYUV(tjhandle handle, unsigned char *srcBuf,
tmpbufsize=0, usetmpbuf=0, th[MAX_COMPONENTS];
JSAMPLE *_tmpbuf=NULL, *ptr=srcBuf; JSAMPROW *tmpbuf[MAX_COMPONENTS];
getinstance(handle)
getinstance(handle);
for(i=0; i<MAX_COMPONENTS; i++)
{

View File

@@ -2,6 +2,8 @@
* wrjpgcom.c
*
* Copyright (C) 1994-1997, Thomas G. Lane.
* libjpeg-turbo Modifications:
* Copyright (C) 2014, D. R. Commander
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -453,6 +455,11 @@ main (int argc, char **argv)
comment_arg = (char *) malloc((size_t) MAX_COM_LENGTH);
if (comment_arg == NULL)
ERREXIT("Insufficient memory");
if (strlen(argv[argn]) + 2 >= (size_t) MAX_COM_LENGTH) {
fprintf(stderr, "Comment text may not exceed %u bytes\n",
(unsigned int) MAX_COM_LENGTH);
exit(EXIT_FAILURE);
}
strcpy(comment_arg, argv[argn]+1);
for (;;) {
comment_length = (unsigned int) strlen(comment_arg);
@@ -462,9 +469,19 @@ main (int argc, char **argv)
}
if (++argn >= argc)
ERREXIT("Missing ending quote mark");
if (strlen(comment_arg) + strlen(argv[argn]) + 2 >=
(size_t) MAX_COM_LENGTH) {
fprintf(stderr, "Comment text may not exceed %u bytes\n",
(unsigned int) MAX_COM_LENGTH);
exit(EXIT_FAILURE);
}
strcat(comment_arg, " ");
strcat(comment_arg, argv[argn]);
}
} else if (strlen(argv[argn]) >= (size_t) MAX_COM_LENGTH) {
fprintf(stderr, "Comment text may not exceed %u bytes\n",
(unsigned int) MAX_COM_LENGTH);
exit(EXIT_FAILURE);
}
comment_length = (unsigned int) strlen(comment_arg);
} else

121
yuvjpeg.c
View File

@@ -41,16 +41,71 @@
#include "jpeglib.h"
void extend_edge(JSAMPLE *image, int width, int height, unsigned char *yuv,
int luma_width, int luma_height, int chroma_width, int chroma_height) {
int x;
int y;
for (y = 0; y < luma_height; y++) {
for (x = 0; x < luma_width; x++) {
image[width*y + x] = yuv[luma_width*y + x];
}
}
for (y = 0; y < chroma_height; y++) {
for (x = 0; x < chroma_width; x++) {
image[width*height + (width/2)*y + x] =
yuv[luma_width*luma_height + chroma_width*y + x];
image[width*height + (width/2)*((height/2) + y) + x] =
yuv[luma_width*luma_height + chroma_width*(chroma_height + y) + x];
}
}
/* Perform right edge extension. */
for (y = 0; y < luma_height; y++) {
for (x = luma_width; x < width; x++) {
image[width*y + x] = image[width*y + (x - 1)];
}
}
for (y = 0; y < chroma_height; y++) {
for (x = chroma_width; x < width/2; x++) {
image[width*height + (width/2)*y + x] =
image[width*height + (width/2)*y + (x - 1)];
image[width*height + (width/2)*((height/2) + y) + x] =
image[width*height + (width/2)*((height/2) + y) + (x - 1)];
}
}
/* Perform bottom edge extension. */
for (x = 0; x < width; x++) {
for (y = luma_height; y < height; y++) {
image[width*y + x] = image[width*(y - 1) + x];
}
}
for (x = 0; x < width/2; x++) {
for (y = chroma_height; y < height/2; y++) {
image[width*height + (width/2)*y + x] =
image[width*height + (width/2)*(y - 1) + x];
image[width*height + (width/2)*((height/2) + y) + x] =
image[width*height + (width/2)*((height/2) + (y - 1)) + x];
}
}
}
int main(int argc, char *argv[]) {
long quality;
const char *size;
char *x;
long width;
long height;
int luma_width;
int luma_height;
int chroma_width;
int chroma_height;
int frame_width;
int frame_height;
const char *yuv_path;
const char *jpg_path;
FILE *yuv_fd;
size_t yuv_size;
unsigned char *yuv_buffer;
JSAMPLE *image_buffer;
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
@@ -64,7 +119,7 @@ int main(int argc, char *argv[]) {
if (argc != 5) {
fprintf(stderr, "Required arguments:\n");
fprintf(stderr, "1. JPEG quality value, 0-100\n");
fprintf(stderr, "2. Image size (e.g. '512x512'\n");
fprintf(stderr, "2. Image size (e.g. '512x512')\n");
fprintf(stderr, "3. Path to YUV input file\n");
fprintf(stderr, "4. Path to JPG output file\n");
return 1;
@@ -84,22 +139,24 @@ int main(int argc, char *argv[]) {
fprintf(stderr, "Invalid image size input!\n");
return 1;
}
width = strtol(size, NULL, 10);
luma_width = (int)strtol(size, NULL, 10);
if (errno != 0) {
fprintf(stderr, "Invalid image size input!\n");
return 1;
}
height = strtol(x + 1, NULL, 10);
luma_height = (int)strtol(x + 1, NULL, 10);
if (errno != 0) {
fprintf(stderr, "Invalid image size input!\n");
return 1;
}
/* Right now we only support dimensions that are multiples of 16. */
if ((width % 16) != 0 || (height % 16) != 0) {
fprintf(stderr, "Image dimensions must be multiples of 16!\n");
if (luma_width <= 0 || luma_height <= 0) {
fprintf(stderr, "Invalid image size input!\n");
return 1;
}
chroma_width = (luma_width + 1) >> 1;
chroma_height = (luma_height + 1) >> 1;
/* Will check these for validity when opening via 'fopen'. */
yuv_path = argv[3];
jpg_path = argv[4];
@@ -113,13 +170,32 @@ int main(int argc, char *argv[]) {
fseek(yuv_fd, 0, SEEK_END);
yuv_size = ftell(yuv_fd);
fseek(yuv_fd, 0, SEEK_SET);
image_buffer = malloc(yuv_size);
if (fread(image_buffer, yuv_size, 1, yuv_fd)!=1) {
/* Check that the file size matches 4:2:0 yuv. */
if (yuv_size !=
(size_t)luma_width*luma_height + 2*chroma_width*chroma_height) {
fprintf(stderr, "Unexpected input format!\n");
return 1;
}
yuv_buffer = malloc(yuv_size);
if (fread(yuv_buffer, yuv_size, 1, yuv_fd) != 1) {
fprintf(stderr, "Error reading yuv file\n");
};
fclose(yuv_fd);
frame_width = (luma_width + (16 - 1)) & ~(16 - 1);
frame_height = (luma_height + (16 - 1)) & ~(16 - 1);
image_buffer =
malloc(frame_width*frame_height + 2*(frame_width/2)*(frame_height/2));
extend_edge(image_buffer, frame_width, frame_height,
yuv_buffer, luma_width, luma_height, chroma_width, chroma_height);
free(yuv_buffer);
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
@@ -131,18 +207,16 @@ int main(int argc, char *argv[]) {
jpeg_stdio_dest(&cinfo, jpg_fd);
cinfo.image_width = width;
cinfo.image_height = height;
cinfo.use_moz_defaults = TRUE;
cinfo.image_width = luma_width;
cinfo.image_height = luma_height;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_YCbCr;
cinfo.use_moz_defaults = TRUE;
jpeg_set_defaults(&cinfo);
cinfo.raw_data_in = TRUE;
#if JPEG_LIB_VERSION >= 70
cinfo.do_fancy_downsampling = FALSE;
#endif
cinfo.comp_info[0].h_samp_factor = 2;
cinfo.comp_info[0].v_samp_factor = 2;
@@ -170,16 +244,19 @@ int main(int argc, char *argv[]) {
plane_pointer[0] = yrow_pointer;
plane_pointer[1] = cbrow_pointer;
plane_pointer[2] = crrow_pointer;
while (cinfo.next_scanline < cinfo.image_height) {
int scanline;
scanline = cinfo.next_scanline;
for (y = 0; y < 16; y++) {
yrow_pointer[y] = image_buffer + cinfo.image_width * (cinfo.next_scanline + y);
yrow_pointer[y] = &image_buffer[frame_width*(scanline + y)];
}
for (y = 0; y < 8; y++) {
cbrow_pointer[y] = image_buffer + width * height +
((width + 1) >> 1) * ((cinfo.next_scanline >> 1) + y);
crrow_pointer[y] = image_buffer + width * height +
((width + 1) >> 1) * ((height + 1) >> 1) +
((width + 1) >> 1) * ((cinfo.next_scanline >> 1) + y);
cbrow_pointer[y] = &image_buffer[frame_width*frame_height +
(frame_width/2)*((scanline/2) + y)];
crrow_pointer[y] = &image_buffer[frame_width*frame_height +
(frame_width/2)*(frame_height/2) + (frame_width/2)*((scanline/2) + y)];
}
jpeg_write_raw_data(&cinfo, plane_pointer, 16);
}