Compare commits

...

336 Commits

Author SHA1 Message Date
DRC
57423076e6 Eliminate all of the __memalign() mess and just handle the alignment ourselves
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@317 632fc199-4ca6-4c93-a231-07263d6284db
2011-01-05 23:35:53 +00:00
DRC
2a2e451ddc Ensure temp. buffers for YUV output are 16-byte aligned on 32-bit Windows
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@316 632fc199-4ca6-4c93-a231-07263d6284db
2011-01-05 22:33:24 +00:00
DRC
990e28dc96 Make arithmetic coding support status messages more clear
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@315 632fc199-4ca6-4c93-a231-07263d6284db
2011-01-04 21:40:11 +00:00
DRC
49aedf4231 Further protect against invalid Huffman codes
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@314 632fc199-4ca6-4c93-a231-07263d6284db
2011-01-04 08:09:41 +00:00
DRC
fa1d18385d Further protect against invalid Huffman codes
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/branches/1.0.x@324 632fc199-4ca6-4c93-a231-07263d6284db
2011-01-26 05:35:20 +00:00
DRC
79778f6588 1.0.2
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/branches/1.0.x@323 632fc199-4ca6-4c93-a231-07263d6284db
2011-01-26 05:34:01 +00:00
DRC
a432ff43a2 Create 1.0.x branch
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/branches/1.0.x@322 632fc199-4ca6-4c93-a231-07263d6284db
2011-01-26 05:23:28 +00:00
DRC
190d5495fe Include new tjDecompressHeader2() function
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@313 632fc199-4ca6-4c93-a231-07263d6284db
2010-12-14 19:48:38 +00:00
DRC
50c657bc09 git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@312 632fc199-4ca6-4c93-a231-07263d6284db 2010-12-14 01:23:16 +00:00
DRC
cad1cfe17c Added YUV decode functionality to the "decompress only" test
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@311 632fc199-4ca6-4c93-a231-07263d6284db
2010-12-14 01:22:00 +00:00
DRC
1fe80f80f5 Added extended tjDecompressHeader() function which can determine the type of subsampling used in the JPEG image
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@310 632fc199-4ca6-4c93-a231-07263d6284db
2010-12-14 01:21:29 +00:00
DRC
a6f4fca72c Fix various memory corruption issues in the new JPEG->YUV feature
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@309 632fc199-4ca6-4c93-a231-07263d6284db
2010-12-11 06:01:11 +00:00
DRC
f9cf5c799d If the output width/height are not an even number of MCU's, then use an intermediate buffer to ensure that the output format is XVideo-compatible
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@308 632fc199-4ca6-4c93-a231-07263d6284db
2010-12-10 10:58:49 +00:00
DRC
9e17f7d9bc Provide TJ_YUV option for tjDecompress() as well
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@307 632fc199-4ca6-4c93-a231-07263d6284db
2010-12-10 04:59:13 +00:00
DRC
ac08ef624c Don't require quality argument when encoding to YUV
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@306 632fc199-4ca6-4c93-a231-07263d6284db
2010-12-09 10:01:57 +00:00
DRC
fbb674707e Merge the TurboJPEG planar YUV encoding feature from VirtualGL 2.2
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@305 632fc199-4ca6-4c93-a231-07263d6284db
2010-11-24 04:02:37 +00:00
DRC
541e651e4c Hide internal SIMD symbols in libjpeg-turbo shared library
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@304 632fc199-4ca6-4c93-a231-07263d6284db
2010-11-23 20:42:48 +00:00
DRC
a46830b232 Eliminate spurious global symbols
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@303 632fc199-4ca6-4c93-a231-07263d6284db
2010-11-23 18:00:46 +00:00
DRC
f0b7fefbf4 Include arithmetic coding test files in dist
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@302 632fc199-4ca6-4c93-a231-07263d6284db
2010-11-23 17:13:02 +00:00
DRC
245cfdf3d6 Allow arithmetic encoding/decoding to be disabled in CMake build
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@301 632fc199-4ca6-4c93-a231-07263d6284db
2010-11-23 17:11:06 +00:00
DRC
e372004b4d Added configure options to disable arithmetic encoding/decoding
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@300 632fc199-4ca6-4c93-a231-07263d6284db
2010-11-23 06:50:14 +00:00
DRC
66f97e6820 Support arithmetic encoding and decoding
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@299 632fc199-4ca6-4c93-a231-07263d6284db
2010-11-23 05:49:54 +00:00
Guido Vollbeding
a4ecaacde6 The Independent JPEG Group's JPEG software v8b 2015-07-27 13:48:40 -05:00
Guido Vollbeding
f18f81b7e2 The Independent JPEG Group's JPEG software v8a 2015-07-27 13:46:36 -05:00
Guido Vollbeding
989630f70c The Independent JPEG Group's JPEG software v8 2015-07-27 13:45:31 -05:00
Guido Vollbeding
5996a25e2f The Independent JPEG Group's JPEG software v7 2015-07-27 13:44:25 -05:00
Guido Vollbeding
1e247ac854 The Independent JPEG Group's JPEG software v6b with arithmetic coding support 2015-07-27 14:40:46 -05:00
Thomas G. Lane
5ead57a34a The Independent JPEG Group's JPEG software v6b 2015-07-27 13:43:00 -05:00
DRC
58842f9679 git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@298 632fc199-4ca6-4c93-a231-07263d6284db 2010-11-23 04:46:59 +00:00
DRC
ec31193812 git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@297 632fc199-4ca6-4c93-a231-07263d6284db 2010-11-22 19:51:42 +00:00
DRC
646e5a8a11 RGBA=RGBX, etc.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@296 632fc199-4ca6-4c93-a231-07263d6284db
2010-11-18 19:55:29 +00:00
DRC
b8841f1ba2 Oops. Still need to explicitly make symlinks in this script, because prefix!=/opt/libjpeg-turbo
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@295 632fc199-4ca6-4c93-a231-07263d6284db
2010-11-17 23:14:53 +00:00
DRC
d1c281a055 Create /opt/libjpeg-turbo/lib32 and /opt/libjpeg-turbo/lib64 symlinks when doing 'make install'
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@294 632fc199-4ca6-4c93-a231-07263d6284db
2010-11-17 22:44:40 +00:00
DRC
61c15bdefb Fix invalid use of fpos_t
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@293 632fc199-4ca6-4c93-a231-07263d6284db
2010-11-13 05:31:25 +00:00
DRC
e89bbaee14 Document jpgtest decompress-only feature
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@292 632fc199-4ca6-4c93-a231-07263d6284db
2010-11-12 10:18:08 +00:00
DRC
e8ce2e0864 Add option to test decompression only + clean up error handling
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@291 632fc199-4ca6-4c93-a231-07263d6284db
2010-11-12 10:14:11 +00:00
DRC
7a0478e1e4 Use version script for jpeg-6b emulation as well
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@290 632fc199-4ca6-4c93-a231-07263d6284db
2010-11-07 19:12:30 +00:00
DRC
7ab9d7cad9 Update header description for grayscale bitmap support
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@289 632fc199-4ca6-4c93-a231-07263d6284db
2010-11-04 22:42:18 +00:00
DRC
09854f57dc Grayscale bitmap support in TurboJPEG/OSS
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@288 632fc199-4ca6-4c93-a231-07263d6284db
2010-11-04 22:39:59 +00:00
DRC
98dbe91270 git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@287 632fc199-4ca6-4c93-a231-07263d6284db 2010-11-04 22:22:30 +00:00
DRC
0f53df8f71 Allow Mac and Solaris packages to be built with v7/v8b emulated libraries
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@286 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-21 19:47:06 +00:00
DRC
8515d3d58d Emulate the version script in libjpeg v7/v8 shared libraries
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@285 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-19 06:38:57 +00:00
DRC
c0a1cba11b Accommodate spaces in CMAKE_BINARY_DIR
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@284 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-18 09:46:27 +00:00
DRC
efa618ecba git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@283 632fc199-4ca6-4c93-a231-07263d6284db 2010-10-18 08:41:11 +00:00
DRC
3a606240f7 1.0.90 (1.1 beta1)
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@282 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-18 08:27:04 +00:00
DRC
9ef93dbbdc Modify OS X universal binary creation process to give the user more control over the 32-bit fork (necessary for building universal binaries with libjpeg v7/v8b emulation, for instance)
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@281 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-18 08:24:42 +00:00
DRC
68bf3f2846 MinGW under Cygwin needs CMAKE_SYSTEM_NAME=Windows as well, since technically, we're cross-compiling
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@280 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-18 07:56:14 +00:00
DRC
81543310fd Cygwin is only supported with the autotools build system
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@279 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-18 07:23:58 +00:00
DRC
5559c900c0 Additional information/corrections involving libjpeg v7/v8b emulation
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@278 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-18 02:21:10 +00:00
DRC
b42a48cc44 Use built-in cmake compare_files function rather than GNU cmp (which isn't natively available on Windows)
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@277 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-18 01:06:36 +00:00
DRC
1f80a10b4e Allow RPMs and SRPMs to be generated with v7/v8b emulation; Add CMake scripts and other missing files to source distribution
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@276 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-18 00:15:31 +00:00
DRC
e2befdef6a Install headers as well
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@275 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-17 07:28:08 +00:00
DRC
310f606b72 Windows packaging has been moved to the CMake build system, so remove it from autotools
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@274 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-17 06:50:35 +00:00
DRC
26658432fb Document 'make install'
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@273 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-16 22:04:29 +00:00
DRC
7284c9a0cd Allow installation from the build system (without needing to build an installer)
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@272 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-16 21:55:14 +00:00
DRC
6f4ba6144a Eliminate redundant dependency statement; Notify user when SIMD is disabled
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@271 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-16 21:27:38 +00:00
DRC
1c73ce8eb5 Additional MinGW recipes
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@270 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-16 21:02:54 +00:00
DRC
b397bfd7db Remove old Windows build system
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@269 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-16 09:23:36 +00:00
DRC
cc2437425b Document new CMake build system
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@268 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-16 09:22:43 +00:00
DRC
b09fde7723 Oops. Forgot to check in header templates
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@267 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-16 08:52:55 +00:00
DRC
2c0a4e1e74 Integrate installer build into CMake build system
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@266 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-16 08:51:43 +00:00
DRC
d830d36074 Fix dependencies for the color conversion routines, which build other .asm files indirectly
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@265 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-15 20:07:41 +00:00
DRC
378da4d61b Print error message if trying to do a native Unix build
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@264 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-15 19:11:11 +00:00
DRC
c869c2c811 Unix LF
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@263 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-15 08:43:32 +00:00
DRC
cd5f2ee23c Allow nasm path to be overridden
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@262 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-15 08:39:44 +00:00
DRC
a9d5b25304 Set version information for DLL's
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@261 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-15 06:42:45 +00:00
DRC
e328bf25f0 Export the correct symbols from the Windows DLL when built with libjpeg v7 or v8b emulation
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@260 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-15 05:33:21 +00:00
DRC
cdd8f123cc Use version suffix on Cygwin DLL as well
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@259 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-15 04:58:13 +00:00
DRC
eb2b9d6b96 Echo version and build
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@258 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-15 04:55:13 +00:00
DRC
846970366b First pass at a CMake build system
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@257 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-15 03:43:24 +00:00
DRC
efa4ddcc88 Space = Tab
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@256 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-13 19:22:50 +00:00
DRC
2edf19d601 Oops. Should be single, not double = sign
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@255 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-13 19:22:20 +00:00
DRC
77e3964ca9 Document the libjpeg v7/v8 extensions
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@254 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-12 03:02:31 +00:00
DRC
766dc5c59d Mention new v7/v8 extensions
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@253 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-12 02:50:18 +00:00
DRC
39ea562c07 Document new v7/v8 features; .doc = .txt
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@252 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-12 01:55:31 +00:00
DRC
ed16ad11ff Enable the use of separate luminance/chrominance quality scaling with libjpeg v6b code base as well
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@251 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-11 23:36:04 +00:00
DRC
12387ebc92 Add sanity check in BMP reader module to avoid cjpeg crash for empty input
image


git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@250 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-10 07:27:26 +00:00
Guido Vollbeding
5829cb2398 The Independent JPEG Group's JPEG software v8d 2015-07-27 13:50:34 -05:00
Guido Vollbeding
c39ec149e8 The Independent JPEG Group's JPEG software v8c 2015-07-27 13:49:31 -05:00
DRC
294079cbe0 Add option for setting luminance & chrominance quality independently (currently only works if using libjpeg v7 or v8 code base)
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@248 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-10 07:21:55 +00:00
DRC
2cdd2ae753 Display libjpeg-turbo version/copyrights in run-time programs
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@247 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-10 06:54:21 +00:00
DRC
517e1c0525 Add -raw option to rdjpgcom for outputting non-printable characters as-is; Make rdjpgcom locale-aware.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@246 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-10 06:04:05 +00:00
DRC
1658c79eba Fix byte order issue with 16bit PPM/PGM files
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@245 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-10 06:01:00 +00:00
DRC
9a648cc90b Fix transpose feature with jpeg v6b code base
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@244 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-10 02:48:21 +00:00
DRC
c04bd3cc97 Implement lossless crop feature from jpeg v7 and v8
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@243 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-10 02:15:56 +00:00
DRC
c54275c6a7 Fix version numbers for v7/v8 shared libs
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@242 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-10 00:40:37 +00:00
DRC
49967cdb30 Improve readability and flexibility of compatibility macros
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@241 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-09 19:57:51 +00:00
DRC
10acd811d0 Remove comments describing DCT scaling feature
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@240 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-09 19:24:28 +00:00
DRC
553d868c25 Oops. Forgot to include the new macro header
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@239 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-09 19:09:41 +00:00
DRC
a5ee9df541 Bump revision to 1.1 alpha
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@238 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-08 08:07:37 +00:00
DRC
eafbe8a056 Bump revision to 1.1 alpha
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@237 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-08 08:07:10 +00:00
DRC
36a6eec932 Added optional emulation of the jpeg-7 or jpeg-8b API/ABI's
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@236 632fc199-4ca6-4c93-a231-07263d6284db
2010-10-08 08:05:44 +00:00
DRC
e5d7bc9f93 "OS/X" = "OS X"
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@235 632fc199-4ca6-4c93-a231-07263d6284db
2010-09-30 18:54:31 +00:00
DRC
9026b37c0b "OS/X"="OS X"
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/branches/1.0.x@581 632fc199-4ca6-4c93-a231-07263d6284db
2011-04-16 13:37:22 +00:00
DRC
254937b33b Update build instructions to reflect the fact that 32-bit LJT build doesn't work with NASM 0.99 or 2.00
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/branches/1.0.x@580 632fc199-4ca6-4c93-a231-07263d6284db
2011-04-16 13:35:35 +00:00
DRC
1da7858d24 MinGW64 no longer prefixes symbols with underscores by default
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/branches/1.0.x@538 632fc199-4ca6-4c93-a231-07263d6284db
2011-03-22 09:34:01 +00:00
DRC
fe6a2ee5a1 Throw a warning if an unexpected marker is found in the middle of the JPEG data stream
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/branches/1.0.x@524 632fc199-4ca6-4c93-a231-07263d6284db
2011-03-18 05:49:26 +00:00
DRC
cce6b43463 Oops. dumpbuf() was displaying only red components.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/branches/1.0.x@430 632fc199-4ca6-4c93-a231-07263d6284db
2011-02-23 01:41:26 +00:00
DRC
d24b276820 Re-order high-quality JPEG test per existing convention
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/branches/1.0.x@390 632fc199-4ca6-4c93-a231-07263d6284db
2011-02-18 05:24:50 +00:00
DRC
94a402305c Also run high-quality JPEG test when code is built without SIMD extensions
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/branches/1.0.x@389 632fc199-4ca6-4c93-a231-07263d6284db
2011-02-18 05:15:59 +00:00
DRC
856fd82ea3 More doc tweaks
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/branches/1.0.x@386 632fc199-4ca6-4c93-a231-07263d6284db
2011-02-18 04:50:45 +00:00
DRC
39f3aa0871 Various documentation tweaks
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/branches/1.0.x@385 632fc199-4ca6-4c93-a231-07263d6284db
2011-02-18 04:39:36 +00:00
DRC
6514105007 Include high-quality test image in distribution
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/branches/1.0.x@384 632fc199-4ca6-4c93-a231-07263d6284db
2011-02-18 03:55:25 +00:00
DRC
6ca69537f1 The SIMD quantization algorithm does not produce correct results with the fast forward integer DCT and JPEG qualities >= 98, so for now, use the non-SIMD quantization function under those circumstances.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/branches/1.0.x@383 632fc199-4ca6-4c93-a231-07263d6284db
2011-02-18 03:31:11 +00:00
DRC
e1716b8507 The fast integer DCT degrades for qualities > 95, so use the slow integer DCT instead to ensure that perceptually lossless performance is maintained.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/branches/1.0.x@381 632fc199-4ca6-4c93-a231-07263d6284db
2011-02-18 03:19:43 +00:00
DRC
e2f3718d39 Fix typo that was causing visual artifacts in grayscale JPEGs
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/branches/1.0.x@377 632fc199-4ca6-4c93-a231-07263d6284db
2011-02-17 07:53:46 +00:00
DRC
af1ca9bcc1 Clarify that the C wrappers and headers fall under the same license as the rest of the SIMD code
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/branches/1.0.x@335 632fc199-4ca6-4c93-a231-07263d6284db
2011-02-02 05:42:37 +00:00
DRC
9dcb1af2f6 git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/branches/1.0.x@328 632fc199-4ca6-4c93-a231-07263d6284db 2011-01-28 07:56:21 +00:00
DRC
585a0172e7 Use testimgflt.ppm in Windows tests
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@233 632fc199-4ca6-4c93-a231-07263d6284db
2010-09-09 22:05:49 +00:00
DRC
5263a8044f Require a full build prior to testing (this fixes a problem whereby running 'make test' on an unbuilt tree would fail)
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@232 632fc199-4ca6-4c93-a231-07263d6284db
2010-09-09 21:02:21 +00:00
DRC
50503c7ac3 Include testimgflt.ppm in distribution
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@231 632fc199-4ca6-4c93-a231-07263d6284db
2010-09-09 21:00:31 +00:00
DRC
c21e538bfb Most of the "nosimd" test images no longer exist, so don't try to include them in the distribution
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@230 632fc199-4ca6-4c93-a231-07263d6284db
2010-09-09 20:40:35 +00:00
DRC
babb815cc0 1.0.1
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@229 632fc199-4ca6-4c93-a231-07263d6284db
2010-09-09 20:34:10 +00:00
DRC
c06073a949 Remove simd/ prefix from #include (not necessary and was causing problems with Visual Studio project)
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@228 632fc199-4ca6-4c93-a231-07263d6284db
2010-09-06 17:37:12 +00:00
DRC
bdb1288e9e Automatically determine whether INCOMPLETE_TYPES_BROKEN should be defined
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@227 632fc199-4ca6-4c93-a231-07263d6284db
2010-08-21 21:14:17 +00:00
DRC
ae7fe0b9ab Clarify licensing
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@226 632fc199-4ca6-4c93-a231-07263d6284db
2010-08-11 21:46:46 +00:00
DRC
025a279ce6 Strike that! Reverse it!
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@225 632fc199-4ca6-4c93-a231-07263d6284db
2010-08-07 16:27:56 +00:00
DRC
3da06c794e No longer need separate test BMP for non-SIMD unit tests
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@224 632fc199-4ca6-4c93-a231-07263d6284db
2010-08-07 16:14:05 +00:00
DRC
30959719ad Fix typo in SIMD dispatch routines which was causing 4:2:0 upsampling to
be used instead of 4:2:2 when decompressing JPEG images using SSE2 code


git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@223 632fc199-4ca6-4c93-a231-07263d6284db
2010-08-07 16:06:56 +00:00
DRC
231a43fc68 Fix build with YASM
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@222 632fc199-4ca6-4c93-a231-07263d6284db
2010-08-03 18:45:11 +00:00
DRC
0fbb28ec39 Handle erroneous Huffman codes
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@221 632fc199-4ca6-4c93-a231-07263d6284db
2010-07-30 17:15:52 +00:00
DRC
bab2941338 1.0.1
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@220 632fc199-4ca6-4c93-a231-07263d6284db
2010-07-30 15:28:22 +00:00
DRC
575c3425ad Document NASM version requirement for 64-bit backward compatible build
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@219 632fc199-4ca6-4c93-a231-07263d6284db
2010-07-08 07:01:20 +00:00
DRC
f1372d29eb We're no longer using the RM macro in Makefile.am, so it doesn't need to be substituted anymore
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@218 632fc199-4ca6-4c93-a231-07263d6284db
2010-07-08 05:41:47 +00:00
DRC
0dedd1ae9a 64-bit support doesn't just exist in 10.6.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@216 632fc199-4ca6-4c93-a231-07263d6284db
2010-07-02 09:20:12 +00:00
DRC
df3337ce8a Log only changes to this source tree, not the external build scripts
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@215 632fc199-4ca6-4c93-a231-07263d6284db
2010-07-02 09:13:58 +00:00
DRC
38ccf8532d git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@214 632fc199-4ca6-4c93-a231-07263d6284db 2010-06-10 19:49:49 +00:00
DRC
7b99172528 Not all platforms define RM
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@213 632fc199-4ca6-4c93-a231-07263d6284db
2010-06-10 19:44:56 +00:00
DRC
13b0944e9b Include non-SIMD test images in distribution
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@212 632fc199-4ca6-4c93-a231-07263d6284db
2010-06-10 18:56:27 +00:00
DRC
83f2144655 Don't require --without-simd to be specified on non-x86 architectures, and fix 'make test' on such architectures
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@211 632fc199-4ca6-4c93-a231-07263d6284db
2010-06-10 18:52:41 +00:00
DRC
bdf7986e7c 1.0.0
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@210 632fc199-4ca6-4c93-a231-07263d6284db
2010-06-10 04:12:48 +00:00
DRC
eadc3c0f91 Cygwin distribution package
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@209 632fc199-4ca6-4c93-a231-07263d6284db
2010-06-09 20:17:09 +00:00
DRC
ae79fdbc2d Cygwin package build
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@208 632fc199-4ca6-4c93-a231-07263d6284db
2010-06-09 20:16:04 +00:00
DRC
c773d10b65 Added bug tracker ID's
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@207 632fc199-4ca6-4c93-a231-07263d6284db
2010-06-05 06:58:22 +00:00
DRC
2093c6380d Oops
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@206 632fc199-4ca6-4c93-a231-07263d6284db
2010-06-05 03:09:17 +00:00
DRC
3d1dd07d54 Ensure that libdir is set properly during build and install so that the run-time library bindings for the binary programs will be correct
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@205 632fc199-4ca6-4c93-a231-07263d6284db
2010-06-05 03:00:36 +00:00
DRC
995c831c5e Remove bin and man directories when uninstalling package
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@204 632fc199-4ca6-4c93-a231-07263d6284db
2010-06-05 01:20:35 +00:00
DRC
cbda81a01d Distribute man pages in source tarball
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@203 632fc199-4ca6-4c93-a231-07263d6284db
2010-06-05 01:12:35 +00:00
DRC
4bf3b585ef git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@202 632fc199-4ca6-4c93-a231-07263d6284db 2010-06-05 01:03:23 +00:00
DRC
e238603c37 Install libjpeg run-time programs and man pages and include in Unix/Linux packages; Create a 32-bit compatibility package for amd64 Debian which has only the 32-bit libraries
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@201 632fc199-4ca6-4c93-a231-07263d6284db
2010-06-05 01:02:38 +00:00
DRC
45d48291f9 Create sym. link from /opt/libjpeg-turbo/lib/64 to /opt/libjpeg-turbo/lib/amd64
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@200 632fc199-4ca6-4c93-a231-07263d6284db
2010-06-05 00:35:18 +00:00
DRC
ff95aa6d36 git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@199 632fc199-4ca6-4c93-a231-07263d6284db 2010-06-05 00:22:32 +00:00
DRC
d90c9a2564 Allow arbitrary package name to be specified
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@198 632fc199-4ca6-4c93-a231-07263d6284db
2010-06-05 00:02:23 +00:00
DRC
8e2bba9e02 Install libjpeg run-time programs and man pages and include in Unix/Linux packages
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@197 632fc199-4ca6-4c93-a231-07263d6284db
2010-06-04 23:54:10 +00:00
DRC
8c2b9fa744 Some Linux platforms require -m32 in the LDFLAGS as well
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@196 632fc199-4ca6-4c93-a231-07263d6284db
2010-06-04 23:09:00 +00:00
DRC
64586cd185 Don't need to use sudo when building Solaris PKG or RPM's
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@195 632fc199-4ca6-4c93-a231-07263d6284db
2010-05-18 22:21:46 +00:00
DRC
e16eaed09c Oops
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@194 632fc199-4ca6-4c93-a231-07263d6284db
2010-05-18 19:18:42 +00:00
DRC
f12c7db429 Create sym links so that headers and static libs can always be found in the same place on Solaris, Linux, and Mac
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@193 632fc199-4ca6-4c93-a231-07263d6284db
2010-05-18 19:04:47 +00:00
DRC
bf5a12db42 Go ahead and set the version to 1.0.0 so all interim builds will be release candidates
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@192 632fc199-4ca6-4c93-a231-07263d6284db
2010-05-18 17:31:32 +00:00
DRC
12fc3eaf63 0.0.94
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@191 632fc199-4ca6-4c93-a231-07263d6284db
2010-05-18 05:32:01 +00:00
DRC
49597877a4 64-bit FreeBSD sets host_cpu to "amd64", not "x86_64". Handle that case so that configure will work without explicitly specifying --host.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@190 632fc199-4ca6-4c93-a231-07263d6284db
2010-05-17 20:47:57 +00:00
DRC
991c2fcae7 Some systems (FreeBSD, in particular) don't define the RM macro in automake
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@189 632fc199-4ca6-4c93-a231-07263d6284db
2010-05-17 20:42:51 +00:00
DRC
4ea16c0603 Define TJ_411 so that VirtualGL <= 2.1.x and TurboVNC <= 0.6 can be built with the libjpeg-turbo SDK
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@188 632fc199-4ca6-4c93-a231-07263d6284db
2010-05-17 16:42:14 +00:00
DRC
377add7ae9 Updated Windows build information
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@187 632fc199-4ca6-4c93-a231-07263d6284db
2010-05-17 16:41:12 +00:00
DRC
a51ada6706 Use new e-mail alias
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@185 632fc199-4ca6-4c93-a231-07263d6284db
2010-05-11 00:39:45 +00:00
DRC
ef663e333e Only disable filesystem redirection in the 64-bit installers
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@184 632fc199-4ca6-4c93-a231-07263d6284db
2010-05-10 23:39:22 +00:00
DRC
be09b20a40 Handle cases in which MinGW inexplicably builds the DLL as libjpeg-0.dll instead of libjpeg-62.dll
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@183 632fc199-4ca6-4c93-a231-07263d6284db
2010-05-10 22:20:14 +00:00
DRC
9ca2364694 Use "make nsi" instead of "make dist" to be consistent with MinGW build
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@182 632fc199-4ca6-4c93-a231-07263d6284db
2010-05-10 22:19:24 +00:00
DRC
3dc1bc2ded Create separate packages for Win64 binaries
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@181 632fc199-4ca6-4c93-a231-07263d6284db
2010-05-10 22:18:10 +00:00
DRC
1a2219ec26 git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@180 632fc199-4ca6-4c93-a231-07263d6284db 2010-05-10 20:03:36 +00:00
DRC
b6f097f729 xmm6-xmm15 must also be preserved by the callee; Win64 should fully work now
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@179 632fc199-4ca6-4c93-a231-07263d6284db
2010-04-23 15:41:34 +00:00
DRC
d3e320fee7 Win64 should fully work now
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@178 632fc199-4ca6-4c93-a231-07263d6284db
2010-04-21 17:20:12 +00:00
DRC
830d5fccf4 Use 64-bit holding buffer on Win64 for increased performance
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@177 632fc199-4ca6-4c93-a231-07263d6284db
2010-04-20 21:13:26 +00:00
DRC
4132b1d552 Updated (C)
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@176 632fc199-4ca6-4c93-a231-07263d6284db
2010-04-20 20:54:03 +00:00
DRC
f9bdeb62e2 Not sure why the cjpeg/djpeg image loaders got disabled, but re-enable them
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@175 632fc199-4ca6-4c93-a231-07263d6284db
2010-04-20 19:16:06 +00:00
DRC
e728ed7a36 Win64 (mostly) works now
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@174 632fc199-4ca6-4c93-a231-07263d6284db
2010-04-20 19:15:09 +00:00
DRC
a644fb05a7 Use correct filenames in headers
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@173 632fc199-4ca6-4c93-a231-07263d6284db
2010-04-20 18:20:13 +00:00
DRC
86d8c0aa26 0.0.93
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@172 632fc199-4ca6-4c93-a231-07263d6284db
2010-04-20 18:12:38 +00:00
DRC
fb096fff78 Only have to use 32-bit mov for r14, since it is populated from the stack
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@171 632fc199-4ca6-4c93-a231-07263d6284db
2010-04-19 18:58:07 +00:00
DRC
14ecb539df Attempt to fix Win64 issues
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@170 632fc199-4ca6-4c93-a231-07263d6284db
2010-04-17 21:57:25 +00:00
DRC
09271951d9 0.0.92
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@169 632fc199-4ca6-4c93-a231-07263d6284db
2010-04-13 07:56:24 +00:00
DRC
7bac07bf12 Added FreeBSD build instructions
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@168 632fc199-4ca6-4c93-a231-07263d6284db
2010-04-10 05:53:35 +00:00
DRC
0f413b2207 Fix x86-64 build on FreeBSD systems
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@167 632fc199-4ca6-4c93-a231-07263d6284db
2010-04-06 20:05:39 +00:00
DRC
97f8ec4b60 I'm not sure why, but this was necessary in order to return the 32-bit performance to the 0.0.90 baseline
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@165 632fc199-4ca6-4c93-a231-07263d6284db
2010-03-20 22:38:53 +00:00
DRC
1e6b5b4884 Clarify license description
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@164 632fc199-4ca6-4c93-a231-07263d6284db
2010-03-20 20:00:51 +00:00
DRC
ae19bf6f15 Add ChangeLog to repository
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@163 632fc199-4ca6-4c93-a231-07263d6284db
2010-03-15 11:40:31 +00:00
DRC
e885a8bf41 Fix data corruption issues when decompressing large JPEG images and/or using buffered I/O. Specifically, decode_mcu_fast() can potentially process more than 1 MCU, so make sure there is enough space in the buffer to accommodate this case. Otherwise, the buffer pointer goes negative, and bad mojo ensues. Also, the fast decoder's method of handling unread markers doesn't make libjpeg's restart handler happy, so disable fast decode when restarts are used.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@162 632fc199-4ca6-4c93-a231-07263d6284db
2010-03-15 11:34:58 +00:00
DRC
0b7d4ed792 Include ChangeLog.txt in dist
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@161 632fc199-4ca6-4c93-a231-07263d6284db
2010-03-03 09:37:58 +00:00
DRC
10a094f0e6 Bump version number
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@160 632fc199-4ca6-4c93-a231-07263d6284db
2010-03-03 09:36:31 +00:00
DRC
f8b77c44f1 Don't allow code path to be forced on a system that doesn't support it
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@159 632fc199-4ca6-4c93-a231-07263d6284db
2010-03-03 08:46:29 +00:00
DRC
048990944f Bleepin' Windows uses LLP64, not LP64
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@158 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-26 23:01:19 +00:00
DRC
d3c7eff53d Oops. Debian users might like documentation as well.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@157 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-25 20:14:10 +00:00
DRC
0248dd9aeb Clarify the DLL hell problem
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@154 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-25 06:21:12 +00:00
DRC
7e0b499ee7 Install jpeg62.dll in SDK directory, not Windows system directory. Also, check whether SDK is already installed prior to re-installing
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@153 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-25 05:52:44 +00:00
DRC
f19caa5e67 Ensure static libs are built with PIC
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@152 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-24 21:27:32 +00:00
DRC
0a1f68edeb Visual C++ libraries can't be made to work with MinGW because of the dependency on msvcr90.dll, so build a separate installer for MinGW libraries
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@151 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-24 07:24:26 +00:00
DRC
8f870c297d 4.0 is significantly slower than 4.1+
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@150 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-24 00:30:00 +00:00
DRC
f66a2b08a2 Get rid of cjpeg/djpeg-specific #defines
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@149 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-23 23:54:28 +00:00
DRC
485cd80811 We don't actually need to use GCC 4.0 to do a backward compatible build, and it slows things down relative to GCC 4.2
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@148 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-23 23:23:42 +00:00
DRC
a9a7b22443 Fix Windows package script to accommodate new output directory for VC build
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@147 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-23 22:56:05 +00:00
DRC
3cd2e503c6 Fix compiler warning about ending struct with a comma
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@146 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-23 21:43:21 +00:00
DRC
fe7936c603 Make sure CFLAGS, CXXFLAGS, LDFLAGS, and host_alias are unset to get a 32-bit build
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@145 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-23 20:17:48 +00:00
DRC
252dbc9fad Oops. Didn't mean to commit the debug statement
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@144 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-23 10:39:07 +00:00
DRC
5df6c2372d For some unknown reason, the sym link and the actual file get flipped around whenever you do 'make install'. Make sure the script handles both cases.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@143 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-23 10:22:33 +00:00
DRC
ca3cebbaef Compile properly with C++
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@142 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-23 08:12:38 +00:00
DRC
4425702a6a Oops. Missing test image
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@141 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-22 22:57:45 +00:00
DRC
968c8bbc00 Fix 'make dist' since we added new test images
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@140 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-22 22:50:13 +00:00
DRC
8f0d62cb92 Added additional documentation for flags
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@139 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-22 08:35:19 +00:00
DRC
0c6a271f97 Make TJ_FORCE* options work correctly
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@138 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-22 08:34:44 +00:00
DRC
3bddd467c4 A bit better solution for 64-bit cleanliness
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@137 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-22 06:14:05 +00:00
DRC
4df84bf859 Clarify Win64 issue
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@136 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-22 04:55:23 +00:00
DRC
748fda3834 Use the C library DLL only with jpeg62.dll where it is needed. Build turbojpeg.dll with the static C library to maintain backward compatibility with TurboJPEG/IPP
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@135 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-22 04:51:09 +00:00
DRC
aa91179eac Speed up make testclean
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@134 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-22 04:12:06 +00:00
DRC
03c3c9be67 Added note about this being an outdated document
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@133 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-21 15:45:00 +00:00
DRC
c3f4ac0b6e Add note about texinfo dependency in NASM build
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@132 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-19 21:51:26 +00:00
DRC
a93881b109 Remove debug output
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@131 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-19 07:01:23 +00:00
DRC
4924e49ad0 test depends on jpegut as well
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@130 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-19 07:00:30 +00:00
DRC
687244b90e Unfortunately, we have to use the DLL version of the C library to avoid crashes in cjpeg
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@129 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-19 06:59:18 +00:00
DRC
9abc855552 Oops. DLL object was misnamed and thus wasn't getting removed on 'make clean'
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@128 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-19 06:56:53 +00:00
DRC
10d15cbe44 Improve unit tests
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@127 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-19 06:56:03 +00:00
DRC
0fd8be5d0c Improve unit tests
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@126 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-19 05:12:39 +00:00
DRC
26b208d8b7 MinGW64 requires that the functions be prefixed with an underscore. Visual C++ apparently doesn't
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@125 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-18 13:14:29 +00:00
DRC
8b014d7f5d First attempt at Win64 support
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@124 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-18 13:03:41 +00:00
DRC
ea1978896e dumpbuf() should have void return type
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@123 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-18 05:12:58 +00:00
DRC
c9327685dd Oops. Leftover bugs from the 64-bit port (cause seg fault when using JDCT_FLOAT or JDCT_IFAST when decompressing)
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@122 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-18 04:14:14 +00:00
DRC
65d05c1d92 Exit with non-zero status if an error is encountered
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@121 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-18 00:40:17 +00:00
DRC
ca5e7d184e Sun Studio recipes
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@120 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-17 02:25:06 +00:00
DRC
b9b1ca30ca Build Sun packages
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@119 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-17 02:24:02 +00:00
DRC
10e75a71da Make sure existing .deb file is removed prior to building new one
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@118 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-17 01:08:37 +00:00
DRC
051dd5a4ab Replace clunky doexit() mechanism with a better means of error trapping
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@117 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-17 01:07:46 +00:00
DRC
6afd256e98 Oops. Need to use %dir to list directories
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@116 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-17 00:56:59 +00:00
DRC
d86e4d914c Build libturbojpeg.so using mapfile on Solaris
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@115 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-16 22:40:26 +00:00
DRC
1e2f298f94 Set default optimization flags to -xO5 if using Sun Studio
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@114 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-16 22:35:25 +00:00
DRC
8a26fdea23 Fix build with Sun Studio
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@113 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-16 22:34:12 +00:00
DRC
23071bcba5 Install additional documentation
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@112 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-16 05:54:00 +00:00
DRC
68fef83ed9 Split build instructions into a new file and add SDK usage notes to README-turbo.txt
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@111 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-16 05:29:10 +00:00
DRC
2f272d519f Make sure directories under /opt/libjpeg-turbo get deleted when uninstalling RPM
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@110 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-16 05:04:46 +00:00
DRC
6f8c66880e Build TurboJPEG/OSS with a version script to prevent any non-global symbols from being accessible (this is to protect against potential namespace conflicts when preloading it into an application via VirtualGL.)
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@109 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-16 05:03:51 +00:00
DRC
45ff6e2745 Create Windows installer
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@108 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-15 17:10:36 +00:00
DRC
fb18e856e4 Keep dllexport symbols out of static lib
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@107 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-15 17:07:46 +00:00
DRC
315123fa3e Add mechanism for building universal (i386/x86-64) binaries on Snow Leopard
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@106 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-15 16:14:26 +00:00
DRC
6a3477c29f Use more appropriate temp. directory name
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@105 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-15 15:16:58 +00:00
DRC
6533b6e023 Add mechanism for creating Mac packages
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@104 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-15 14:57:18 +00:00
DRC
268ef884d8 Use a cleaner method of arg checking that works with set -u
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@103 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-15 13:32:09 +00:00
DRC
4614871092 Instructions for Tiger-compatible build on Leopard/Snow Leopard
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@102 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-15 13:27:17 +00:00
DRC
feb9dce665 Oops. This should have been included with r100
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@101 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-15 12:08:46 +00:00
DRC
52a19f25d5 Add mechanism for creating DEB packages
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@100 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-15 12:06:27 +00:00
DRC
f26914b93a Actually, we only need to 'make dist-gzip' prior to building the SRPM
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@99 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-15 11:36:46 +00:00
DRC
079b4346bc Add mechanism for creating RPMs
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@98 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-15 11:32:23 +00:00
DRC
6f52592267 Should really use $(srcdir) here
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@97 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-15 11:10:08 +00:00
DRC
8ff1f254f3 Change default prefix to /opt/libjpeg-turbo
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@96 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-15 11:08:57 +00:00
DRC
211de3b963 Don't need Visual C++ project file
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@95 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-15 11:07:33 +00:00
DRC
ec84a6bdbf Change package name & version
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@94 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-15 11:05:53 +00:00
DRC
0a945a1770 Make sure 'make dist' includes everything we want (and nothing we don't)
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@93 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-15 11:04:51 +00:00
DRC
6aa6a0a768 More missing files from jpeg-6b
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@92 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-15 10:49:01 +00:00
DRC
4d5fc18f58 Reflect the fact that CFLAGS=CXXFLAGS=-O3 by default
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@91 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-14 08:02:55 +00:00
DRC
e7b699d653 Set CFLAGS=CXXFLAGS=-O3 if using GCC and the flags are not already set
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@90 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-14 07:39:07 +00:00
DRC
327184fbee builddir isn't always defined
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@89 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-14 02:15:52 +00:00
DRC
ce1546eb90 License info + updated performance claims
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@88 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-13 23:06:03 +00:00
DRC
971d851844 Enable (i.e. fix) VPATH and out-of-tree builds
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@87 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-13 22:55:05 +00:00
DRC
bd17e2a5d6 Instructions for cross compiling MinGW libs on Cygwin
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@86 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-12 23:24:21 +00:00
DRC
101f09a3d1 Build instructions
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@85 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-12 22:52:37 +00:00
DRC
bf0fab9aa1 MinGW uses autoconf 2.56
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@84 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-12 22:22:01 +00:00
DRC
f4253a7cdd Visual C++ build
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@83 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-12 09:37:20 +00:00
DRC
34d59e71d6 Clean up test detritus
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@82 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-12 06:27:34 +00:00
DRC
60fa0600c0 Re-add relevant files and tests from libjpeg v6b
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@81 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-12 06:01:49 +00:00
DRC
60cddeb849 Restore --without-simd option for testing purposes
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@80 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-12 05:37:07 +00:00
DRC
21d66837a0 Do not build libturbojpeg as a versioned library
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@79 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-12 04:34:41 +00:00
DRC
411dcf5666 Oops. Still need to #define WITH_SIMD
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@78 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-12 04:28:29 +00:00
DRC
87581b8188 Make SIMD build compulsory (otherwise, what's the point?)
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@77 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-11 06:57:57 +00:00
DRC
1bf1a14d71 Build shared libraries by default; Include libturbojpeg in distribution
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@76 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-11 06:39:32 +00:00
DRC
4f4428185b Oops. Use EGREP instead of GREP, because GREP is not available in earlier versions of autotools
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@75 632fc199-4ca6-4c93-a231-07263d6284db
2010-02-05 09:19:13 +00:00
DRC
2a46aeece8 Fix build problems on Solaris 10
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@74 632fc199-4ca6-4c93-a231-07263d6284db
2010-01-29 07:14:57 +00:00
DRC
83e9cd5e36 Enable 64-bit libjpeg/SIMD build on Solaris
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@73 632fc199-4ca6-4c93-a231-07263d6284db
2010-01-28 23:57:53 +00:00
DRC
a1e9878b31 Use the correct version to name the shared library, and if the shared library build is enabled, allow the headers to be installed
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@72 632fc199-4ca6-4c93-a231-07263d6284db
2010-01-28 22:18:41 +00:00
DRC
0c0f304e8d Allow building libjpeg.so if --enable-shared is passed to configure (but disable shared library build by default)
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@71 632fc199-4ca6-4c93-a231-07263d6284db
2010-01-28 05:34:53 +00:00
Adam Tkac
e54fb0bf95 [Bugfix] Mark stack as non-executable in NASM code.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@70 632fc199-4ca6-4c93-a231-07263d6284db
2010-01-27 10:10:23 +00:00
Pierre Ossman
1536192e92 Update the svn:ignore lists for the new build system.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@69 632fc199-4ca6-4c93-a231-07263d6284db
2009-12-23 09:24:42 +00:00
DRC
321ad51314 Enable 64-bit build on Snow Leopard
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@68 632fc199-4ca6-4c93-a231-07263d6284db
2009-10-08 09:41:39 +00:00
DRC
132b5fdd6d Work around alignment issue with OS X linker which was causing problems on Leopard and Snow Leopard
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@67 632fc199-4ca6-4c93-a231-07263d6284db
2009-10-08 09:04:56 +00:00
DRC
fc5dc4fa19 Some systems (notably OS X Leopard) have fls() already, so rename ours to avoid conflict
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@66 632fc199-4ca6-4c93-a231-07263d6284db
2009-10-01 22:26:14 +00:00
DRC
021da085a7 Not all platforms define __WORDSIZE
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@65 632fc199-4ca6-4c93-a231-07263d6284db
2009-09-28 08:19:40 +00:00
DRC
e2816648d8 Greatly improve performance of Huffman decoding
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@64 632fc199-4ca6-4c93-a231-07263d6284db
2009-09-28 00:33:02 +00:00
DRC
6c0e1fc72e Significantly improve grayscale performance
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@63 632fc199-4ca6-4c93-a231-07263d6284db
2009-09-24 06:18:25 +00:00
Adam Tkac
0ba6826d20 Merge unified_buildsys branch to trunk (r3892 - r3898)
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@62 632fc199-4ca6-4c93-a231-07263d6284db
2009-09-14 13:07:14 +00:00
DRC
a21a01c60d Update (C) notice and fix line feed in usage instructions
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@61 632fc199-4ca6-4c93-a231-07263d6284db
2009-09-03 01:35:12 +00:00
Peter Åstrand
353332b015 Corrected last patch: Use jsimd_none.c instead of jsimd_i386.c on
VC/Windows at this point. 



git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@60 632fc199-4ca6-4c93-a231-07263d6284db
2009-08-19 14:20:46 +00:00
Peter Åstrand
adfd23393c Windows build fixes:
* Use jsimd_i386.c instead of the attic jsimd.c

* Corrected include of jsimd.h in jsimd_i386.c. 



git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@59 632fc199-4ca6-4c93-a231-07263d6284db
2009-08-19 13:53:48 +00:00
DRC
dae4474117 Unfortunately, the previous enhancements made an invalid assumption about the code sizes, which caused "DCT out of range" errors in the decoder. Was able to fix 64-bit without losing any performance, but unfortunately had to revert 32-bit back to its previous behavior for now.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@58 632fc199-4ca6-4c93-a231-07263d6284db
2009-08-06 08:58:48 +00:00
DRC
8ece7fef15 Update copyrights to indicate files modified with colorspace extensions
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@57 632fc199-4ca6-4c93-a231-07263d6284db
2009-08-06 08:32:00 +00:00
DRC
62aaa7e7c1 Oops. Clean up a couple of remaining 32-bit memory accesses
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@56 632fc199-4ca6-4c93-a231-07263d6284db
2009-08-06 07:51:26 +00:00
DRC
8443e529e9 Improve compression performance by 15-20%
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@55 632fc199-4ca6-4c93-a231-07263d6284db
2009-07-30 08:35:06 +00:00
Pierre Ossman
5d20b7e662 Make our Makefile.am a bit easier to convert to a standalone one by
indicating which headers are the public ones.


git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@54 632fc199-4ca6-4c93-a231-07263d6284db
2009-07-10 12:59:14 +00:00
Pierre Ossman
79ecd1b16e Make sure bmp.h gets distributed.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@53 632fc199-4ca6-4c93-a231-07263d6284db
2009-07-10 12:56:00 +00:00
Pierre Ossman
f1418c76a8 Make sure the indirectly used assembly files get packaged.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@52 632fc199-4ca6-4c93-a231-07263d6284db
2009-07-10 12:47:13 +00:00
Pierre Ossman
9a6b8dca7e Make x86_64 SIMD code PIC friendly
Use RIP relative addressing as that works in both PIC and non-PIC mode.


git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@51 632fc199-4ca6-4c93-a231-07263d6284db
2009-06-29 12:58:48 +00:00
Pierre Ossman
db838bdb73 Ignore test tools and files generated by them
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@50 632fc199-4ca6-4c93-a231-07263d6284db
2009-06-29 11:24:50 +00:00
Pierre Ossman
ba82ddf6ca Clean up SIMD glue code
The SIMD glue code has gotten a bit #ifdef heavy so clean it up by having
one file for each possible SIMD arch. This also allows a simplification of
the x86_64 code as SSE/SSE2 is always known to exist on that arch.


git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@49 632fc199-4ca6-4c93-a231-07263d6284db
2009-06-29 11:20:42 +00:00
Pierre Ossman
1aea5fa182 Remove unused variable.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@48 632fc199-4ca6-4c93-a231-07263d6284db
2009-06-26 14:10:33 +00:00
Pierre Ossman
afa937e62b Improve the messages for the SIMD configuration test now that we support
more than one arch.


git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@47 632fc199-4ca6-4c93-a231-07263d6284db
2009-06-26 14:09:47 +00:00
DRC
73de982473 Add back in cjpeg and djpeg utilities for testing purposes
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@46 632fc199-4ca6-4c93-a231-07263d6284db
2009-06-25 20:41:17 +00:00
DRC
cdc8ac3eb1 64-bit SIMD acceleration
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@45 632fc199-4ca6-4c93-a231-07263d6284db
2009-06-25 20:38:31 +00:00
DRC
3a63184474 Fix dependencies for merged upsampling code
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@44 632fc199-4ca6-4c93-a231-07263d6284db
2009-06-25 20:33:51 +00:00
DRC
61e51f98e2 Test fast upsampling
"4:1:1 = 4:2:0"


git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@43 632fc199-4ca6-4c93-a231-07263d6284db
2009-04-05 21:53:20 +00:00
DRC
720e161083 Add colorspace extensions to merged upsampling routines
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@42 632fc199-4ca6-4c93-a231-07263d6284db
2009-04-05 21:51:25 +00:00
DRC
e673a1764a Remove unnecessary code
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@41 632fc199-4ca6-4c93-a231-07263d6284db
2009-04-05 21:47:40 +00:00
DRC
16ed1f5387 Oops. jcolsamp.inc should be included from j[c|d]clr[mmx|ss2].asm so it received the effect of the redefined RGB_* macros
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@40 632fc199-4ca6-4c93-a231-07263d6284db
2009-04-04 15:25:45 +00:00
DRC
a2d19e1981 Oops. jcolsamp.inc needs to be included from j[c|d]clr[mmx|ss2].asm so that it receives the effect of the redefined RGB_* macros
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@39 632fc199-4ca6-4c93-a231-07263d6284db
2009-04-04 15:22:14 +00:00
Adam Tkac
6e8b69d35f Don't install test programs, build them only.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@38 632fc199-4ca6-4c93-a231-07263d6284db
2009-04-03 14:54:40 +00:00
Adam Tkac
6e075fcfae Check if C++ compiler is present.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@37 632fc199-4ca6-4c93-a231-07263d6284db
2009-04-03 14:47:50 +00:00
DRC
2e7b76b28c Include low-level unit tests borrowed from VirtualGL
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@36 632fc199-4ca6-4c93-a231-07263d6284db
2009-04-03 12:04:24 +00:00
DRC
f25c071eb7 Implement new colorspaces to allow directly compressing from/decompressing to RGB/RGBX/BGR/BGRX/XBGR/XRGB without conversion
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@35 632fc199-4ca6-4c93-a231-07263d6284db
2009-04-03 12:00:51 +00:00
DRC
59c1a252d5 Add environment variables to force MMX/SSE2 code path selection
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@34 632fc199-4ca6-4c93-a231-07263d6284db
2009-04-03 11:27:17 +00:00
DRC
c7fbf2961a Fix build for RGB_PIXELSIZE==4
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@33 632fc199-4ca6-4c93-a231-07263d6284db
2009-04-01 20:02:14 +00:00
DRC
3cba8db08f Eliminate backward incompatibility that required empty_output_buffer() to handle cases in which the buffer wasn't 100% full
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@32 632fc199-4ca6-4c93-a231-07263d6284db
2009-03-16 23:58:30 +00:00
Pierre Ossman
3a65ef478b Work around subdirectory bug in older automake.
Older versions of automake doesn't properly support no-recursive make.
Reimplement the build system by having a local Makefile.am in the
simd/ directory.


git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@31 632fc199-4ca6-4c93-a231-07263d6284db
2009-03-16 13:34:18 +00:00
DRC
8629988742 Fix broken buffered I/O (to make cjpeg work)
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@30 632fc199-4ca6-4c93-a231-07263d6284db
2009-03-14 01:21:13 +00:00
Adam Tkac
d07a0a6479 Make source compilable via GNU autotools which are part of RHEL 5.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@29 632fc199-4ca6-4c93-a231-07263d6284db
2009-03-13 13:58:44 +00:00
Adam Tkac
6a8b33d3cd Revert r3657 (import of autogenerated) files.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@28 632fc199-4ca6-4c93-a231-07263d6284db
2009-03-13 13:44:18 +00:00
Pierre Ossman
995a3e14ee Add new simd files to Visual Studio project file.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@27 632fc199-4ca6-4c93-a231-07263d6284db
2009-03-13 12:24:28 +00:00
Pierre Ossman
dc5db14a33 Move variable init around a bit to please crappy compilers.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@26 632fc199-4ca6-4c93-a231-07263d6284db
2009-03-13 12:17:26 +00:00
Pierre Ossman
b28e287f93 Don't mix LOCAL() and qualifiers.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@25 632fc199-4ca6-4c93-a231-07263d6284db
2009-03-13 12:16:51 +00:00
DRC
99313388cc Include Huffman codec optimizations borrowed from TurboJPEG
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@24 632fc199-4ca6-4c93-a231-07263d6284db
2009-03-12 17:24:27 +00:00
Adam Tkac
0747ad2b12 Import autogenerated files for unix/ and common/ subdirs to make source
compilable without GNU autotools.



git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@23 632fc199-4ca6-4c93-a231-07263d6284db
2009-03-11 11:14:37 +00:00
Pierre Ossman
eea7215525 Add SSE2 SIMD implementation of computationally intensive routines.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@22 632fc199-4ca6-4c93-a231-07263d6284db
2009-03-09 13:34:17 +00:00
MIYASAKA Masaru
a2e6a9dd47 IJG R6b with x86SIMD V1.02
Independent JPEG Group's JPEG software release 6b
with x86 SIMD extension for IJG JPEG library version 1.02
2015-07-29 16:36:25 -05:00
Pierre Ossman
018fc42974 Add SSE SIMD implementation of computationally intensive routines.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@21 632fc199-4ca6-4c93-a231-07263d6284db
2009-03-09 13:31:56 +00:00
Pierre Ossman
7311830680 Most SIMD implementations need 16 byte alignment
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@20 632fc199-4ca6-4c93-a231-07263d6284db
2009-03-09 13:30:47 +00:00
Pierre Ossman
35c4719638 Make sure the work space memory is properly aligned
We use the heap allocators to avoid having more than one implementation
of the alignment logic.


git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@19 632fc199-4ca6-4c93-a231-07263d6284db
2009-03-09 13:29:37 +00:00
Pierre Ossman
65d0317346 Add 3DNow SIMD implementation of computationally intensive routines.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@18 632fc199-4ca6-4c93-a231-07263d6284db
2009-03-09 13:28:10 +00:00
Pierre Ossman
5eb84ff97f Add MMX SIMD implementation of computationally intensive routines.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@17 632fc199-4ca6-4c93-a231-07263d6284db
2009-03-09 13:25:30 +00:00
Pierre Ossman
dedc42e268 "Optimise" quantization step by replacing the division by a multiplication.
This has no measurable difference right now but makes it possible to do
SIMD implementations of this stage.


git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@16 632fc199-4ca6-4c93-a231-07263d6284db
2009-03-09 13:23:04 +00:00
Pierre Ossman
2ae181c7b8 Implement x86 SIMD framework
Add NASM support and stub routine for detecting SIMD extensions.


git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@15 632fc199-4ca6-4c93-a231-07263d6284db
2009-03-09 13:21:27 +00:00
Pierre Ossman
59a3938b2e Framework for supporting SIMD acceleration
Designed to impose minimal changes on the "normal" code.


git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@14 632fc199-4ca6-4c93-a231-07263d6284db
2009-03-09 13:15:56 +00:00
Pierre Ossman
49dcbfbf13 Split up the forward DCT routine into three stages
Divide it into sample conversion, DCT and quantization in order to
easily provide alternative implementations of each stage.


git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@13 632fc199-4ca6-4c93-a231-07263d6284db
2009-03-09 10:37:20 +00:00
Pierre Ossman
5557fd2217 Improve memory allocater alignment handling
Fix some broken assumptions and allow any alignment, not just those
associated with C types.


git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@12 632fc199-4ca6-4c93-a231-07263d6284db
2009-03-09 10:34:53 +00:00
Pierre Ossman
2fb0831aeb Ignore generated configuration header.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@11 632fc199-4ca6-4c93-a231-07263d6284db
2009-03-09 10:33:17 +00:00
Pierre Ossman
ba0ce39b70 Explain the config header voodoo.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@10 632fc199-4ca6-4c93-a231-07263d6284db
2009-03-06 15:30:42 +00:00
Pierre Ossman
b22e883a5f Don't test for GNU malloc as we don't need it (or even check the result
of the test).


git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@9 632fc199-4ca6-4c93-a231-07263d6284db
2009-03-06 15:00:56 +00:00
Peter Åstrand
aa026fbf36 Renamed README_TightVNC.txt as README_TigerVNC.txt
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@8 632fc199-4ca6-4c93-a231-07263d6284db
2009-03-03 12:04:47 +00:00
Peter Åstrand
8a418b2bb8 Rebrand the source as TigerVNC. It is my hope that this patch is
minimal but still complete. The rebranding was done using a script:

find trunk -name .svn -prune -o -type f -exec rep.sh \{\} \;
pushd trunk
svn revert doc/TODO doc/registered-codes.txt doc/ft-protocol-problems.txt doc/rfbtight.tex
perl -pi -e 's|tightvnc|tigervnc|g' unix/configure.ac win/configure.ac unix/README

With rep.sh looking like:

perl -pi -e 's|TightVNC|TigerVNC|g' "$@"
perl -pi -e 's|www\.tightvnc\.com/bugs\.html|www\.tigervnc\.org|g' "$@"
perl -pi -e 's|www\.tightvnc\.com|www\.tigervnc\.org|g' "$@"
perl -pi -e 's|devteam\@tightvnc\.com|tigervnc-devel\@lists\.sourceforge\.net|g' "$@"
perl -pi -e 's|TigerVNC Team|TightVNC Team|g' "$@"
perl -pi -e 's|TigerVNC Group|TightVNC Group|g' "$@"
perl -pi -e 's|TigerVNC protocol|TightVNC protocol|g' "$@"
perl -pi -e 's|TigerVNC-specific|TightVNC-specific|g' "$@"
perl -pi -e 's|Vendor signatures: standard VNC/RealVNC, TridiaVNC, and TigerVNC|Vendor signatures: standard VNC/RealVNC, TridiaVNC, and TightVNC|g' "$@"
perl -pi -e 's|TigerVNC vendor|TightVNC vendor|g' "$@"
perl -pi -e 's|TigerVNC extension|TightVNC extension|g' "$@"
perl -pi -e 's|protocolTigerVNC|protocolTightVNC|g' "$@"
perl -pi -e 's|TigerVNC additions were|TightVNC additions were|g' "$@"
perl -pi -e 's|TigerVNC 1\.2|TightVNC 1\.2|g' "$@"
perl -pi -e 's|TigerVNC authentication type|TightVNC authentication type|g' "$@"



git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@7 632fc199-4ca6-4c93-a231-07263d6284db
2009-02-27 10:12:14 +00:00
Peter Åstrand
5f33883e0e Ignoring Autotools and build files.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@6 632fc199-4ca6-4c93-a231-07263d6284db
2008-12-10 08:50:48 +00:00
Peter Åstrand
213a72aaea This should be the final modification to restore a working Visual
Studio build. A static jconfig.h has been re-added, but in a separate
directory, to avoid clash with jconfig.h generated by configure
script. Also, jconfig.h now includes the inline macro. jpeg.dsp has
been modified to search in the "win" subdir, to find jconfig.h. 

This patch is in spirit similar to r121. 



git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@5 632fc199-4ca6-4c93-a231-07263d6284db
2008-12-02 09:56:26 +00:00
Adam Tkac
da5a1fe760 [Bugfix] Include man files and more jpeg libraries in tarball
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@3 632fc199-4ca6-4c93-a231-07263d6284db
2008-10-22 11:19:25 +00:00
Constantin Kaplinsky
0ca44258fc Merged changes from branches/1.5-xserver (revision range 2432:2631) back to trunk.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@2 632fc199-4ca6-4c93-a231-07263d6284db
2008-09-28 05:08:48 +00:00
Constantin Kaplinsky
c87530727a Migrating to new directory structure adopted from the RealVNC's source tree. More changes will follow.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@1 632fc199-4ca6-4c93-a231-07263d6284db
2006-05-25 05:01:55 +00:00
245 changed files with 41993 additions and 10332 deletions

607
BUILDING.txt Normal file
View File

@@ -0,0 +1,607 @@
*******************************************************************************
** Building on Unix Platforms (including Cygwin)
*******************************************************************************
==================
Build Requirements
==================
-- autoconf 2.56 or later
-- automake 1.7 or later
-- libtool 1.4 or later
-- NASM
* 0.98 or later is required for a 32-bit build
* NASM 2.05 or later is required for a 64-bit build
* NASM 2.07 or later is required for a 64-bit build on OS X. This can be
obtained from MacPorts (http://www.macports.org/).
The NASM 2.05 RPMs do not work on older Linux systems, such as Red Hat
Enterprise Linux 4. On such systems, you can easily build and install NASM
2.05 from the source RPM by executing the following as root:
ARCH=`uname -m`
wget http://www.nasm.us/pub/nasm/releasebuilds/2.05.01/nasm-2.05.01-1.src.rpm
rpmbuild --rebuild nasm-2.05.01-1.src.rpm
rpm -Uvh /usr/src/redhat/RPMS/$ARCH/nasm-2.05.01-1.$ARCH.rpm
NOTE: NASM build will fail if texinfo is not installed.
-- GCC v4.1 or later recommended for best performance
==================
Out-of-Tree Builds
==================
Binary objects, libraries, and executables are generated in the same directory
from which configure was executed (the "binary directory"), and this directory
need not necessarily be the same as the libjpeg-turbo source directory. You
can create multiple independent binary directories, in which different versions
of libjpeg-turbo can be built from the same source tree using different
compilers or settings. In the sections below, {build_directory} refers to the
binary directory, whereas {source_directory} refers to the libjpeg-turbo source
directory. For in-tree builds, these directories are the same.
======================
Building libjpeg-turbo
======================
The following procedure will build libjpeg-turbo on Linux, FreeBSD, 32-bit
OS X, Cygwin, and Solaris/x86 systems (on Solaris, this generates a 32-bit
library. See below for 64-bit build instructions.)
cd {source_directory}
autoreconf -fiv
cd {build_directory}
sh {source_directory}/configure [additional configure flags]
make
NOTE: Running autoreconf in the source directory is only necessary if building
libjpeg-turbo from the SVN repository.
This will generate the following files under .libs/
libjpeg.a
Static link library for libjpeg-turbo
libjpeg.so.{version} (Linux, Solaris)
libjpeg.{version}.dylib (OS X)
cygjpeg-{version}.dll (Cygwin)
Shared library for libjpeg-turbo
libjpeg.so (Linux, Solaris)
libjpeg.dylib (OS X)
libjpeg.dll.a (Cygwin)
Development stub for libjpeg-turbo shared library
libturbojpeg.a
Static link library for TurboJPEG/OSS
libturbojpeg.so (Linux, Solaris)
libturbojpeg.dylib (OS X)
Shared library and development stub for TurboJPEG/OSS
cygturbojpeg.dll (Cygwin)
Shared library for TurboJPEG/OSS
libturbojpeg.dll.a (Cygwin)
Development stub for TurboJPEG/OSS shared library
{version} is 62.0.0, 7.0.0, or 8.0.2, depending on whether libjpeg v6b
(default), v7, or v8b emulation is enabled. If using Cygwin, {version} is
62, 7, or 8.
libjpeg v7 or v8b Emulation
---------------------------
Add --with-jpeg7 to the configure command line to build a version of
libjpeg-turbo that is compatible with libjpeg v7. Add --with-jpeg8 to the
configure command to build a version of libjpeg-turbo that is compatible with
libjpeg v8b. See README-turbo.txt for more information on libjpeg v7 and v8b
emulation.
Arithmetic Coding Support
-------------------------
Since the patent on arithmetic coding has expired, this functionality has been
included in this release of libjpeg-turbo. libjpeg-turbo's implementation is
based on the implementation in libjpeg v8b, but it works when emulating libjpeg
v7 or v6b as well. The default is to enable both arithmetic encoding and
decoding, but those who have philosophical objections to arithmetic coding can
add --without-arith-enc or --without-arith-dec to the configure command line to
disable encoding or decoding (respectively.)
========================
Installing libjpeg-turbo
========================
If you intend to install these libraries and the associated header files, then
replace 'make' in the instructions above with
make install prefix={base dir} libdir={library directory}
For example,
make install prefix=/usr/local libdir=/usr/local/lib64
will install the header files in /usr/local/include and the library files in
/usr/local/lib64. If 'prefix' and 'libdir' are not specified, then the default
is to install the header files in /opt/libjpeg-turbo/include and the library
files in /opt/libjpeg-turbo/lib.
NOTE: You can specify a prefix of /usr and a libdir of, for instance,
/usr/lib64 to overwrite the system's version of libjpeg. If you do this,
however, then be sure to BACK UP YOUR SYSTEM'S INSTALLATION OF LIBJPEG before
overwriting it. It is recommended that you instead install libjpeg-turbo into
a non-system directory and manipulate the LD_LIBRARY_PATH or create sym links
to force applications to use libjpeg-turbo instead of libjpeg. See
README-turbo.txt for more information.
=============
Build Recipes
=============
32-bit Library Build on 64-bit Linux
------------------------------------
Add
--host i686-pc-linux-gnu CFLAGS='-O3 -m32' CXXFLAGS='-O3 -m32' LDFLAGS=-m32
to the configure command line.
64-bit Library Build on 64-bit OS X
-----------------------------------
Add
--host x86_64-apple-darwin NASM=/opt/local/bin/nasm
to the configure command line. NASM 2.07 or later from MacPorts must be
installed.
32-bit Library Build on 64-bit OS X
-----------------------------------
Add
CFLAGS='-O3 -m32' CXXFLAGS='-O3 -m32' LDFLAGS=-m32
to the configure command line.
64-bit Backward-Compatible Library Build on 64-bit OS X
-------------------------------------------------------
Add
--host x86_64-apple-darwin NASM=/opt/local/bin/nasm \
CFLAGS='-isysroot /Developer/SDKs/MacOSX10.4u.sdk \
-mmacosx-version-min=10.4 -O3' \
CXXFLAGS='-isysroot /Developer/SDKs/MacOSX10.4u.sdk \
-mmacosx-version-min=10.4 -O3' \
LDFLAGS='-isysroot /Developer/SDKs/MacOSX10.4u.sdk \
-mmacosx-version-min=10.4'
to the configure command line. The OS X 10.4 SDK, and NASM 2.07 or later from
MacPorts, must be installed.
32-bit Backward-Compatible Library Build on OS X
------------------------------------------------
Add
CFLAGS='-isysroot /Developer/SDKs/MacOSX10.4u.sdk \
-mmacosx-version-min=10.4 -O3 -m32' \
CXXFLAGS='-isysroot /Developer/SDKs/MacOSX10.4u.sdk \
-mmacosx-version-min=10.4 -O3 -m32' \
LDFLAGS='-isysroot /Developer/SDKs/MacOSX10.4u.sdk \
-mmacosx-version-min=10.4 -m32'
to the configure command line. The OS X 10.4 SDK must be installed.
64-bit Library Build on 64-bit Solaris
--------------------------------------
Add
--host x86_64-pc-solaris CFLAGS='-O3 -m64' CXXFLAGS='-O3 -m64' LDFLAGS=-m64
to the configure command line.
32-bit Library Build on 64-bit FreeBSD
--------------------------------------
Add
--host i386-unknown-freebsd CC='gcc -B /usr/lib32' CXX='g++ -B/usr/lib32' \
CFLAGS='-O3 -m32' CXXFLAGS='-O3 -m32' LDFLAGS='-B/usr/lib32'
to the configure command line. NASM 2.07 or later from FreeBSD ports must be
installed.
Sun Studio
----------
Add
CC=cc CXX=CC
to the configure command line. libjpeg-turbo will automatically be built with
the maximum optimization level (-xO5) unless you override CFLAGS and CXXFLAGS.
To build a 64-bit version of libjpeg-turbo using Sun Studio, add
--host x86_64-pc-solaris CC=cc CXX=CC CFLAGS='-xO5 -m64' \
CXXFLAGS='-xO5 -m64' LDFLAGS=-m64
to the configure command line.
MinGW Build on Cygwin
---------------------
Use CMake (see recipes below)
*******************************************************************************
** Building on Windows (Visual C++ or MinGW)
*******************************************************************************
==================
Build Requirements
==================
-- CMake (http://www.cmake.org) v2.6 or later
-- Microsoft Visual C++ 2005 or later
If you don't already have Visual C++, then the easiest way to get it is by
installing the Windows SDK:
http://msdn.microsoft.com/en-us/windows/bb980924.aspx
The Windows SDK includes both 32-bit and 64-bit Visual C++ compilers and
everything necessary to build libjpeg-turbo.
* For 32-bit builds, you can also use Microsoft Visual C++ Express
Edition. Visual C++ Express Edition is a free download.
* If you intend to build libjpeg-turbo from the command line, then add the
appropriate compiler and SDK directories to the INCLUDE, LIB, and PATH
environment variables. This is generally accomplished by executing
vcvars32.bat or vcvars64.bat and SetEnv.cmd. vcvars32.bat and
vcvars64.bat are part of Visual C++ and are located in the same directory
as the compiler. SetEnv.cmd is part of the Windows SDK. You can pass
optional arguments to SetEnv.cmd to specify a 32-bit or 64-bit build
environment.
... OR ...
-- MinGW
GCC v4.1 or later recommended for best performance
-- NASM (http://www.nasm.us/) 0.98 or later (NASM 2.05 or later is required for
a 64-bit build)
==================
Out-of-Tree Builds
==================
Binary objects, libraries, and executables are generated in the same directory
from which cmake was executed (the "binary directory"), and this directory need
not necessarily be the same as the libjpeg-turbo source directory. You can
create multiple independent binary directories, in which different versions of
libjpeg-turbo can be built from the same source tree using different compilers
or settings. In the sections below, {build_directory} refers to the binary
directory, whereas {source_directory} refers to the libjpeg-turbo source
directory. For in-tree builds, these directories are the same.
======================
Building libjpeg-turbo
======================
Visual C++ (Command Line)
-------------------------
cd {build_directory}
cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release {source_directory}
nmake
This will build either a 32-bit or a 64-bit version of libjpeg-turbo, depending
on which version of cl.exe is in the PATH.
The following files will be generated under {build_directory}:
jpeg-static.lib
Static link library for libjpeg-turbo
sharedlib/jpeg{version}.dll
DLL for libjpeg-turbo
sharedlib/jpeg.lib
Import library for libjpeg-turbo DLL
turbojpeg-static.lib
Static link library for TurboJPEG/OSS
turbojpeg.dll
DLL for TurboJPEG/OSS
turbojpeg.lib
Import library for TurboJPEG/OSS DLL
{version} is 62, 7, or 8, depending on whether libjpeg v6b (default), v7, or
v8b emulation is enabled.
Visual C++ (IDE)
----------------
Choose the appropriate CMake generator option for your version of Visual Studio
(run "cmake" with no arguments for a list of available generators.) For
instance:
cd {build_directory}
cmake -G "Visual Studio 9 2008" {source_directory}
You can then open ALL_BUILD.vcproj in Visual Studio and build one of the
configurations in that project ("Debug", "Release", etc.) to generate a full
build of libjpeg-turbo.
This will generate the following files under {build_directory}:
{configuration}/jpeg-static.lib
Static link library for libjpeg-turbo
sharedlib/{configuration}/jpeg{version}.dll
DLL for libjpeg-turbo
sharedlib/{configuration}/jpeg.lib
Import library for libjpeg-turbo DLL
{configuration}/turbojpeg-static.lib
Static link library for TurboJPEG/OSS
{configuration}/turbojpeg.dll
DLL for TurboJPEG/OSS
{configuration}/turbojpeg.lib
Import library for TurboJPEG/OSS DLL
{configuration} is Debug, Release, RelWithDebInfo, or MinSizeRel, depending on
the configuration you built in the IDE, and {version} is 62, 7, or 8,
depending on whether libjpeg v6b (default), v7, or v8b emulation is enabled.
MinGW
-----
cd {build_directory}
cmake -G "MSYS Makefiles" {source_directory}
make
This will generate the following files under {build_directory}
libjpeg.a
Static link library for libjpeg-turbo
sharedlib/libjpeg-{version}.dll
DLL for libjpeg-turbo
sharedlib/libjpeg.dll.a
Import library for libjpeg-turbo DLL
libturbojpeg.a
Static link library for TurboJPEG/OSS
libturbojpeg.dll
DLL for TurboJPEG/OSS
libturbojpeg.dll.a
Import library for TurboJPEG/OSS DLL
{version} is 62, 7, or 8, depending on whether libjpeg v6b (default), v7, or
v8b emulation is enabled.
Debug Build
-----------
Add "-DCMAKE_BUILD_TYPE=Debug" to the cmake command line. Or, if building with
NMake, remove "-DCMAKE_BUILD_TYPE=Release" (Debug builds are the default with
NMake.)
libjpeg v7 or v8b Emulation
---------------------------
Add "-DWITH_JPEG7=1" to the cmake command line to build a version of
libjpeg-turbo that is compatible with libjpeg v7. Add "-DWITH_JPEG8=1" to the
cmake command to build a version of libjpeg-turbo that is compatible with
libjpeg v8b. See README-turbo.txt for more information on libjpeg v7 and v8b
emulation.
Arithmetic Coding Support
-------------------------
Since the patent on arithmetic coding has expired, this functionality has been
included in this release of libjpeg-turbo. libjpeg-turbo's implementation is
based on the implementation in libjpeg v8b, but it works when emulating libjpeg
v7 or v6b as well. The default is to enable both arithmetic encoding and
decoding, but those who have philosophical objections to arithmetic coding can
add "-DWITH_ARITH_ENC=0" or "-DWITH_ARITH_DEC=0" to the cmake command line to
disable encoding or decoding (respectively.)
========================
Installing libjpeg-turbo
========================
You can use the build system to install libjpeg-turbo into a directory of your
choosing (as opposed to creating an installer.) To do this, add:
-DCMAKE_INSTALL_PREFIX={install_directory}
to the cmake command line.
For example,
cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=c:\libjpeg-turbo {source_directory}
nmake install
will install the header files in c:\libjpeg-turbo\include, the library files
in c:\libjpeg-turbo\lib, the DLL's in c:\libjpeg-turbo\bin, and the
documentation in c:\libjpeg-turbo\doc.
=============
Build Recipes
=============
64-bit MinGW Build on Cygwin
----------------------------
cd {build_directory}
CC=/usr/bin/x86_64-w64-mingw32-gcc CXX=/usr/bin/x86_64-w64-mingw32-g++ \
cmake -G "Unix Makefiles" -DCMAKE_SYSTEM_NAME=Windows \
-DCMAKE_AR=/usr/bin/x86_64-w64-mingw32-ar \
-DCMAKE_RANLIB=/usr/bin/x86_64-w64-mingw32-ranlib {source_directory}
make
This produces a 64-bit build of libjpeg-turbo that does not depend on
cygwin1.dll or other Cygwin DLL's. The mingw64-x86_64-gcc-core and
mingw64-x86_64-gcc-g++ packages (and their dependencies) must be installed.
32-bit MinGW Build on Cygwin
----------------------------
cd {build_directory}
CC=/usr/bin/i686-w64-mingw32-gcc CXX=/usr/bin/i686-w64-mingw32-g++ \
cmake -G "Unix Makefiles" -DCMAKE_SYSTEM_NAME=Windows \
-DDCMAKE_AR=/usr/bin/i686-w64-mingw32-ar \
-DCMAKE_RANLIB=/usr/bin/i686-w64-mingw32-ranlib {source_directory}
make
This produces a 32-bit build of libjpeg-turbo that does not depend on
cygwin1.dll or other Cygwin DLL's. The mingw64-i686-gcc-core and
mingw64-i686-gcc-g++ packages (and their dependencies) must be installed.
MinGW-w64 Build on Windows
--------------------------
This produces a 64-bit build of libjpeg-turbo using the "native" MinGW-w64
toolchain (which is faster than the Cygwin version):
cd {build_directory}
CC={mingw-w64_binary_path}/x86_64-w64-mingw32-gcc \
CXX={mingw-w64_binary_path}/x86_64-w64-mingw32-g++ \
cmake -G "MSYS Makefiles" \
-DCMAKE_AR={mingw-w64_binary_path}/x86_64-w64-mingw32-ar \
-DCMAKE_RANLIB={mingw-w64_binary_path}/x86_64-w64-mingw32-ranlib \
{source_directory}
make
MinGW Build on Linux
--------------------
cd {build_directory}
CC={mingw_binary_path}/i386-mingw32-gcc \
CXX={mingw_binary_path}/i386-mingw32-g++ \
cmake -G "Unix Makefiles" -DCMAKE_SYSTEM_NAME=Windows \
-DCMAKE_AR={mingw_binary_path}/i386-mingw32-ar \
-DCMAKE_RANLIB={mingw_binary_path}/i386-mingw32-ranlib \
{source_directory}
make
*******************************************************************************
** Creating Release Packages
*******************************************************************************
The following commands can be used to create various types of release packages:
Unix
----
make rpm
Create Red Hat-style binary RPM package. Requires RPM v4 or later.
make srpm
This runs 'make dist' to create a pristine source tarball, then creates a
Red Hat-style source RPM package from the tarball. Requires RPM v4 or later.
make deb
Create Debian-style binary package. Requires dpkg.
make dmg
Create Macintosh package/disk image. This requires the PackageMaker
application, which must be installed in /Developer/Applications/Utilities.
make udmg [BUILDDIR32={32-bit build directory}]
On 64-bit OS X systems, this creates a version of the Macintosh package and
disk image which contains universal i386/x86-64 binaries. You should first
configure a 32-bit out-of-tree build of libjpeg-turbo, then configure a
64-bit out-of-tree build, then run 'make udmg' from the 64-bit build
directory. The build system will look for the 32-bit build under
{source_directory}/osxx86 by default, but you can override this by setting
the BUILDDIR32 variable on the make command line as shown above.
make sunpkg
Build a Solaris package. This requires pkgmk, pkgtrans, and bzip2.
make csunpkg [BUILDDIR32={32-bit build directory}]
On 64-bit Solaris systems, this creates a combined package which contains
both 32-bit and 64-bit libraries. You should first configure a 32-bit
out-of-tree build of libjpeg-turbo, then configure a 64-bit out-of-tree
build, then run 'make csunpkg' from the 64-bit build directory. The build
system will look for the 32-bit build under {source_directory}/solx86 by
default, but you can override this by setting the BUILDDIR32 variable on the
make command line as shown above.
make cygwinpkg
Build a Cygwin binary package.
Windows
-------
If using NMake:
cd {build_directory}
nmake installer
If using MinGW:
cd {build_directory}
make installer
If using the Visual Studio IDE, build the "installer" project.
The installer package (libjpeg-turbo[-gcc][64].exe) will be located under
{build_directory}. If building using the Visual Studio IDE, then the installer
package will be located in a subdirectory with the same name as the
configuration you built (such as {build_directory}\Debug\ or
{build_directory}\Release\).
Building a Windows installer requires the Nullsoft Install System
(http://nsis.sourceforge.net/.) makensis.exe should be in your PATH.

344
CMakeLists.txt Normal file
View File

@@ -0,0 +1,344 @@
#
# Setup
#
cmake_minimum_required(VERSION 2.6)
project(libjpeg-turbo)
set(VERSION 1.0.90)
if(MINGW OR CYGWIN)
execute_process(COMMAND "date" "+%Y%m%d" OUTPUT_VARIABLE BUILD)
string(REGEX REPLACE "\n" "" BUILD ${BUILD})
elseif(WIN32)
execute_process(COMMAND "${CMAKE_SOURCE_DIR}/cmakescripts/getdate.bat"
OUTPUT_VARIABLE BUILD)
string(REGEX REPLACE "\n" "" BUILD ${BUILD})
else()
message(FATAL_ERROR "Platform not supported by this build system. Use autotools instead.")
endif()
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
message(STATUS "CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}")
# This only works if building from the command line. There is currently no way
# to set a variable's value based on the build type when using the MSVC IDE.
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(BUILD "${BUILD}d")
endif()
message(STATUS "VERSION = ${VERSION}, BUILD = ${BUILD}")
if(NOT DEFINED WITH_SIMD)
set(WITH_SIMD 1)
endif()
if(NOT DEFINED WITH_ARITH_ENC)
set(WITH_ARITH_ENC 1)
endif()
if(NOT DEFINED WITH_ARITH_DEC)
set(WITH_ARITH_DEC 1)
endif()
if(WITH_ARITH_ENC)
set(C_ARITH_CODING_SUPPORTED 1)
message(STATUS "Arithmetic encoding support enabled")
else()
message(STATUS "Arithmetic encoding support disabled")
endif()
if(WITH_ARITH_DEC)
set(D_ARITH_CODING_SUPPORTED 1)
message(STATUS "Arithmetic decoding support enabled")
else()
message(STATUS "Arithmetic decoding support disabled")
endif()
set(JPEG_LIB_VERSION 62)
set(DLL_VERSION ${JPEG_LIB_VERSION})
set(FULLVERSION ${DLL_VERSION}.0.0)
if(WITH_JPEG8)
set(JPEG_LIB_VERSION 80)
set(DLL_VERSION 8)
set(FULLVERSION ${DLL_VERSION}.0.2)
message(STATUS "Emulating libjpeg v8b API/ABI")
elseif(WITH_JPEG7)
set(JPEG_LIB_VERSION 70)
set(DLL_VERSION 7)
set(FULLVERSION ${DLL_VERSION}.0.0)
message(STATUS "Emulating libjpeg v7 API/ABI")
endif(WITH_JPEG8)
if(MSVC)
# Use the static C library for all build types
foreach(var CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
if(${var} MATCHES "/MD")
string(REGEX REPLACE "/MD" "/MT" ${var} "${${var}}")
endif()
endforeach()
add_definitions(-W3 -wd4996)
endif()
# Detect whether compiler is 64-bit
if(MSVC AND CMAKE_CL_64)
set(SIMD_X86_64 1)
set(64BIT 1)
elseif(CMAKE_SIZEOF_VOID_P MATCHES 8)
set(SIMD_X86_64 1)
set(64BIT 1)
endif()
if(64BIT)
message(STATUS "64-bit build")
else()
message(STATUS "32-bit build")
endif()
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})
#
# Targets
#
set(JPEG_SOURCES jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c
jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c jcphuff.c
jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c jdatadst.c jdatasrc.c
jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c jdinput.c jdmainct.c jdmarker.c
jdmaster.c jdmerge.c jdphuff.c jdpostct.c jdsample.c jdtrans.c jerror.c
jfdctflt.c jfdctfst.c jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c
jquant1.c jquant2.c jutils.c jmemmgr.c jmemnobs.c)
if(WITH_ARITH_ENC OR WITH_ARITH_DEC)
set(JPEG_SOURCES ${JPEG_SOURCES} jaricom.c)
endif()
if(WITH_ARITH_ENC)
set(JPEG_SOURCES ${JPEG_SOURCES} jcarith.c)
endif()
if(WITH_ARITH_DEC)
set(JPEG_SOURCES ${JPEG_SOURCES} jdarith.c)
endif()
if(WITH_SIMD)
add_definitions(-DWITH_SIMD)
add_subdirectory(simd)
if(SIMD_X86_64)
set(JPEG_SOURCES ${JPEG_SOURCES} simd/jsimd_x86_64.c)
else()
set(JPEG_SOURCES ${JPEG_SOURCES} simd/jsimd_i386.c)
endif()
# This tells CMake that the "source" files haven't been generated yet
set_source_files_properties(${SIMD_OBJS} PROPERTIES GENERATED 1)
else()
set(JPEG_SOURCES ${JPEG_SOURCES} jsimd_none.c)
message(STATUS "Not using SIMD acceleration")
endif()
add_subdirectory(sharedlib)
add_library(jpeg-static STATIC ${JPEG_SOURCES} ${SIMD_OBJS})
if(NOT MSVC)
set_target_properties(jpeg-static PROPERTIES OUTPUT_NAME jpeg)
endif()
if(WITH_SIMD)
add_dependencies(jpeg-static simd)
endif()
add_library(turbojpeg SHARED turbojpegl.c)
set_target_properties(turbojpeg PROPERTIES DEFINE_SYMBOL DLLDEFINE)
target_link_libraries(turbojpeg jpeg-static)
set_target_properties(turbojpeg PROPERTIES LINK_INTERFACE_LIBRARIES "")
add_library(turbojpeg-static STATIC ${JPEG_SOURCES} ${SIMD_OBJS}
turbojpegl.c)
if(NOT MSVC)
set_target_properties(turbojpeg-static PROPERTIES OUTPUT_NAME turbojpeg)
endif()
if(WITH_SIMD)
add_dependencies(turbojpeg-static simd)
endif()
add_executable(jpegut jpegut.c)
target_link_libraries(jpegut turbojpeg)
add_executable(jpegut-static jpegut.c)
target_link_libraries(jpegut-static turbojpeg-static)
add_executable(jpgtest jpgtest.cxx bmp.c)
target_link_libraries(jpgtest turbojpeg)
add_executable(jpgtest-static jpgtest.cxx bmp.c)
target_link_libraries(jpgtest-static turbojpeg-static)
add_executable(cjpeg-static cjpeg.c cdjpeg.c rdbmp.c rdgif.c rdppm.c rdswitch.c
rdtarga.c)
set_property(TARGET cjpeg-static PROPERTY COMPILE_FLAGS
"-DBMP_SUPPORTED -DGIF_SUPPORTED -DPPM_SUPPORTED -DTARGA_SUPPORTED")
target_link_libraries(cjpeg-static jpeg-static)
add_executable(djpeg-static djpeg.c cdjpeg.c rdcolmap.c rdswitch.c wrbmp.c wrgif.c
wrppm.c wrtarga.c)
set_property(TARGET djpeg-static PROPERTY COMPILE_FLAGS
"-DBMP_SUPPORTED -DGIF_SUPPORTED -DPPM_SUPPORTED -DTARGA_SUPPORTED")
target_link_libraries(djpeg-static jpeg-static)
add_executable(jpegtran-static jpegtran.c cdjpeg.c rdswitch.c transupp.c)
target_link_libraries(jpegtran-static jpeg-static)
add_executable(rdjpgcom rdjpgcom.c)
add_executable(wrjpgcom rdjpgcom.c)
#
# Tests
#
enable_testing()
add_test(jpegut jpegut)
add_test(jpegut-yuv jpegut -yuv)
add_test(cjpeg-int sharedlib/cjpeg -dct int -outfile testoutint.jpg ${CMAKE_SOURCE_DIR}/testorig.ppm)
add_test(cjpeg-int-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_SOURCE_DIR}/testimgint.jpg testoutint.jpg)
add_test(cjpeg-fast sharedlib/cjpeg -dct fast -opt -outfile testoutfst.jpg ${CMAKE_SOURCE_DIR}/testorig.ppm)
add_test(cjpeg-fast-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_SOURCE_DIR}/testimgfst.jpg testoutfst.jpg)
add_test(cjpeg-float sharedlib/cjpeg -dct float -outfile testoutflt.jpg ${CMAKE_SOURCE_DIR}/testorig.ppm)
if(WITH_SIMD)
add_test(cjpeg-float-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_SOURCE_DIR}/testimgflt.jpg testoutflt.jpg)
else()
add_test(cjpeg-float-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_SOURCE_DIR}/testimgflt-nosimd.jpg testoutflt.jpg)
endif()
add_test(djpeg-int sharedlib/djpeg -dct int -fast -ppm -outfile testoutint.ppm ${CMAKE_SOURCE_DIR}/testorig.jpg)
add_test(djpeg-int-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_SOURCE_DIR}/testimgint.ppm testoutint.ppm)
add_test(djpeg-fast sharedlib/djpeg -dct fast -ppm -outfile testoutfst.ppm ${CMAKE_SOURCE_DIR}/testorig.jpg)
add_test(djpeg-fast-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_SOURCE_DIR}/testimgfst.ppm testoutfst.ppm)
add_test(djpeg-float sharedlib/djpeg -dct float -ppm -outfile testoutflt.ppm ${CMAKE_SOURCE_DIR}/testorig.jpg)
if(WITH_SIMD)
add_test(djpeg-float-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_SOURCE_DIR}/testimgflt.ppm testoutflt.ppm)
else()
add_test(djpeg-float-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_SOURCE_DIR}/testorig.ppm testoutflt.ppm)
endif()
add_test(djpeg-256 sharedlib/djpeg -dct int -bmp -colors 256 -outfile testout.bmp ${CMAKE_SOURCE_DIR}/testorig.jpg)
add_test(djpeg-256-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_SOURCE_DIR}/testimg.bmp testout.bmp)
add_test(cjpeg-prog sharedlib/cjpeg -dct int -progressive -outfile testoutp.jpg ${CMAKE_SOURCE_DIR}/testorig.ppm)
add_test(cjpeg-prog-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_SOURCE_DIR}/testimgp.jpg testoutp.jpg)
add_test(jpegtran-prog sharedlib/jpegtran -outfile testoutt.jpg testoutp.jpg)
add_test(jpegtran-prog-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_SOURCE_DIR}/testimgint.jpg testoutt.jpg)
if(WITH_ARITH_ENC)
add_test(cjpeg-ari sharedlib/cjpeg -dct int -arithmetic -outfile testoutari.jpg ${CMAKE_SOURCE_DIR}/testorig.ppm)
add_test(cjpeg-ari-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_SOURCE_DIR}/testimgari.jpg testoutari.jpg)
add_test(jpegtran-toari sharedlib/jpegtran -arithmetic -outfile testouta.jpg ${CMAKE_SOURCE_DIR}/testimgint.jpg)
add_test(jpegtran-toari-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_SOURCE_DIR}/testimgari.jpg testouta.jpg)
endif()
if(WITH_ARITH_DEC)
add_test(djpeg-ari sharedlib/djpeg -dct int -fast -ppm -outfile testoutari.ppm ${CMAKE_SOURCE_DIR}/testimgari.jpg)
add_test(djpeg-ari-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_SOURCE_DIR}/testimgari.ppm testoutari.ppm)
add_test(jpegtran-fromari sharedlib/jpegtran -outfile testouta.jpg ${CMAKE_SOURCE_DIR}/testimgari.jpg)
add_test(jpegtran-fromari-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_SOURCE_DIR}/testimgint.jpg testouta.jpg)
endif()
add_test(jpegtran-crop sharedlib/jpegtran -crop 120x90+20+50 -transpose -perfect -outfile testoutcrop.jpg ${CMAKE_SOURCE_DIR}/testorig.jpg)
add_test(jpegtran-crop-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_SOURCE_DIR}/testimgcrop.jpg testoutcrop.jpg)
add_test(jpegut-static jpegut-static)
add_test(jpegut-static-yuv jpegut-static -yuv)
add_test(cjpeg-static-int cjpeg-static -dct int -outfile testoutint.jpg ${CMAKE_SOURCE_DIR}/testorig.ppm)
add_test(cjpeg-static-int-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_SOURCE_DIR}/testimgint.jpg testoutint.jpg)
add_test(cjpeg-static-fast cjpeg-static -dct fast -opt -outfile testoutfst.jpg ${CMAKE_SOURCE_DIR}/testorig.ppm)
add_test(cjpeg-static-fast-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_SOURCE_DIR}/testimgfst.jpg testoutfst.jpg)
add_test(cjpeg-static-float cjpeg-static -dct float -outfile testoutflt.jpg ${CMAKE_SOURCE_DIR}/testorig.ppm)
if(WITH_SIMD)
add_test(cjpeg-static-float-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_SOURCE_DIR}/testimgflt.jpg testoutflt.jpg)
else()
add_test(cjpeg-static-float-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_SOURCE_DIR}/testimgflt-nosimd.jpg testoutflt.jpg)
endif()
add_test(djpeg-static-int djpeg-static -dct int -fast -ppm -outfile testoutint.ppm ${CMAKE_SOURCE_DIR}/testorig.jpg)
add_test(djpeg-static-int-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_SOURCE_DIR}/testimgint.ppm testoutint.ppm)
add_test(djpeg-static-fast djpeg-static -dct fast -ppm -outfile testoutfst.ppm ${CMAKE_SOURCE_DIR}/testorig.jpg)
add_test(djpeg-static-fast-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_SOURCE_DIR}/testimgfst.ppm testoutfst.ppm)
add_test(djpeg-static-float djpeg-static -dct float -ppm -outfile testoutflt.ppm ${CMAKE_SOURCE_DIR}/testorig.jpg)
if(WITH_SIMD)
add_test(djpeg-static-float-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_SOURCE_DIR}/testimgflt.ppm testoutflt.ppm)
else()
add_test(djpeg-static-float-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_SOURCE_DIR}/testorig.ppm testoutflt.ppm)
endif()
add_test(djpeg-static-256 djpeg-static -dct int -bmp -colors 256 -outfile testout.bmp ${CMAKE_SOURCE_DIR}/testorig.jpg)
add_test(djpeg-static-256-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_SOURCE_DIR}/testimg.bmp testout.bmp)
add_test(cjpeg-static-prog cjpeg-static -dct int -progressive -outfile testoutp.jpg ${CMAKE_SOURCE_DIR}/testorig.ppm)
add_test(cjpeg-static-prog-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_SOURCE_DIR}/testimgp.jpg testoutp.jpg)
add_test(jpegtran-static-prog jpegtran-static -outfile testoutt.jpg testoutp.jpg)
add_test(jpegtran-static-prog-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_SOURCE_DIR}/testimgint.jpg testoutt.jpg)
if(WITH_ARITH_ENC)
add_test(cjpeg-static-ari cjpeg-static -dct int -arithmetic -outfile testoutari.jpg ${CMAKE_SOURCE_DIR}/testorig.ppm)
add_test(cjpeg-static-ari-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_SOURCE_DIR}/testimgari.jpg testoutari.jpg)
add_test(jpegtran-static-toari jpegtran-static -arithmetic -outfile testouta.jpg ${CMAKE_SOURCE_DIR}/testimgint.jpg)
add_test(jpegtran-static-toari-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_SOURCE_DIR}/testimgari.jpg testouta.jpg)
endif()
if(WITH_ARITH_DEC)
add_test(djpeg-static-ari djpeg-static -dct int -fast -ppm -outfile testoutari.ppm ${CMAKE_SOURCE_DIR}/testimgari.jpg)
add_test(djpeg-static-ari-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_SOURCE_DIR}/testimgari.ppm testoutari.ppm)
add_test(jpegtran-static-fromari jpegtran-static -outfile testouta.jpg ${CMAKE_SOURCE_DIR}/testimgari.jpg)
add_test(jpegtran-static-fromari-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_SOURCE_DIR}/testimgint.jpg testouta.jpg)
endif()
add_test(jpegtran-static-crop jpegtran-static -crop 120x90+20+50 -transpose -perfect -outfile testoutcrop.jpg ${CMAKE_SOURCE_DIR}/testorig.jpg)
add_test(jpegtran-static-crop-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_SOURCE_DIR}/testimgcrop.jpg testoutcrop.jpg)
#
# Installer
#
set(INST_NAME ${CMAKE_PROJECT_NAME})
if(MSVC)
set(INST_PLATFORM "Visual C++")
elseif(MINGW)
set(INST_PLATFORM GCC)
set(INST_NAME ${INST_NAME}-gcc)
set(INST_DEFS -DGCC)
endif()
if(64BIT)
set(INST_PLATFORM "${INST_PLATFORM} 64-bit")
set(INST_NAME ${INST_NAME}64)
set(INST_DEFS ${INST_DEFS} -DWIN64)
endif()
if(MSVC_IDE)
set(INST_DEFS ${INST_DEFS} "-DBUILDDIR=$(OutDir)\\")
else()
set(INST_DEFS ${INST_DEFS} "-DBUILDDIR=")
endif()
configure_file(release/libjpeg-turbo.nsi.in libjpeg-turbo.nsi @ONLY)
add_custom_target(installer
makensis -nocd ${INST_DEFS} libjpeg-turbo.nsi
DEPENDS jpeg jpeg-static turbojpeg turbojpeg-static
SOURCES libjpeg-turbo.nsi)
install(TARGETS jpeg-static turbojpeg turbojpeg-static rdjpgcom wrjpgcom
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin
)
install(FILES ${CMAKE_SOURCE_DIR}/LGPL.txt ${CMAKE_SOURCE_DIR}/LICENSE.txt
${CMAKE_SOURCE_DIR}/README ${CMAKE_SOURCE_DIR}/README-turbo.txt
${CMAKE_SOURCE_DIR}/libjpeg.txt ${CMAKE_SOURCE_DIR}/usage.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)

86
ChangeLog.txt Normal file
View File

@@ -0,0 +1,86 @@
Significant changes since 1.0.1
===============================
[1] Added emulation of the libjpeg v7 and v8b APIs and ABIs. See
README-turbo.txt for more details. This feature was sponsored by CamTrace SAS.
[2] Created a new CMake-based build system for the Visual C++ and MinGW builds.
[3] TurboJPEG/OSS can now compress from/decompress to grayscale bitmaps.
[4] jpgtest can now be used to test decompression performance only.
[5] If the default install prefix (/opt/libjpeg-turbo) is used, then
'make install' now creates /opt/libjpeg-turbo/lib32 and
/opt/libjpeg-turbo/lib64 sym links to duplicate the behavior of the binary
packages.
[6] All symbols in the libjpeg-turbo dynamic library are now versioned, even
when the library is built with libjpeg v6b emulation.
[7] Added arithmetic encoding and decoding support (can be disabled via
configure or CMake options)
[8] Added a TJ_YUV flag to TurboJPEG/OSS which causes both the compressor and
decompressor to output planar YUV images.
[9] Added an extended version of tjDecompressHeader() to TurboJPEG/OSS which
allows the caller to determine the type of subsampling used in a JPEG image.
[10] Added further protections against invalid Huffman codes.
Significant changes since 1.0.0
===============================
[1] The Huffman decoder will now handle erroneous Huffman codes (for instance,
from a corrupt JPEG image.) Previously, these would cause libjpeg-turbo to
crash under certain circumstances.
[2] Fixed typo in SIMD dispatch routines which was causing 4:2:2 upsampling to
be used instead of 4:2:0 when decompressing JPEG images using SSE2 code.
[3] configure script will now automatically determine whether the
INCOMPLETE_TYPES_BROKEN macro should be defined.
Significant changes since 0.0.93
================================
[1] 2983700: Further FreeBSD build tweaks (no longer necessary to specify
--host when configuring on a 64-bit system)
[2] Created sym. links in the Unix/Linux packages so that the TurboJPEG
include file can always be found in /opt/libjpeg-turbo/include, the 32-bit
static libraries can always be found in /opt/libjpeg-turbo/lib32, and the
64-bit static libraries can always be found in /opt/libjpeg-turbo/lib64.
[3] The Unix/Linux distribution packages now include the libjpeg run-time
programs (cjpeg, etc.) and man pages.
[4] Created a 32-bit supplementary package for amd64 Debian systems which
contains just the 32-bit libjpeg-turbo libraries.
[5] Moved the libraries from */lib32 to */lib in the i386 Debian package.
[6] Include distribution package for Cygwin
[7] No longer necessary to specify --without-simd on non-x86 architectures, and
unit tests now work on those architectures.
Significant changes since 0.0.91
================================
[1] 2982659, Fixed x86-64 build on FreeBSD systems
[2] 2988188: Added support for Windows 64-bit systems
Significant changes since 0.0.90
================================
[1] Added documentation to .deb packages
[2] 2968313: Fixed data corruption issues when decompressing large JPEG images
and/or using buffered I/O with the libjpeg-turbo decompressor

504
LGPL.txt Normal file
View File

@@ -0,0 +1,504 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

53
LICENSE.txt Normal file
View File

@@ -0,0 +1,53 @@
wxWindows Library Licence, Version 3.1
======================================
Copyright (C) 1998-2005 Julian Smart, Robert Roebling et al
Everyone is permitted to copy and distribute verbatim copies
of this licence document, but changing it is not allowed.
WXWINDOWS LIBRARY LICENCE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public Licence as published by
the Free Software Foundation; either version 2 of the Licence, or (at
your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library
General Public Licence for more details.
You should have received a copy of the GNU Library General Public Licence
along with this software, usually in a file named COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA.
EXCEPTION NOTICE
1. As a special exception, the copyright holders of this library give
permission for additional uses of the text contained in this release of
the library as licenced under the wxWindows Library Licence, applying
either version 3.1 of the Licence, or (at your option) any later version of
the Licence as published by the copyright holders of version
3.1 of the Licence document.
2. The exception is that you may use, copy, link, modify and distribute
under your own terms, binary object code versions of works based
on the Library.
3. If you copy code from files distributed under the terms of the GNU
General Public Licence or the GNU Library General Public Licence into a
copy of this library, as this licence permits, the exception does not
apply to the code that you add in this way. To avoid misleading anyone as
to the status of such modified files, you must delete this exception
notice from such code and/or adjust the licensing conditions notice
accordingly.
4. If you write modifications of your own for this library, it is your
choice whether to permit this exception to apply to your modifications.
If you do not wish that, you must delete the exception notice from such
code and/or adjust the licensing conditions notice accordingly.

261
Makefile.am Normal file
View File

@@ -0,0 +1,261 @@
lib_LTLIBRARIES = libjpeg.la libturbojpeg.la
libjpeg_la_LDFLAGS = -version-info ${SO_MAJOR_VERSION}:${SO_MINOR_VERSION} -no-undefined
libturbojpeg_la_LDFLAGS = -avoid-version -no-undefined
include_HEADERS = jerror.h jmorecfg.h jpeglib.h turbojpeg.h
nodist_include_HEADERS = jconfig.h
HDRS = jchuff.h jdct.h jdhuff.h jerror.h jinclude.h jmemsys.h jmorecfg.h \
jpegint.h jpeglib.h jversion.h jsimd.h jsimddct.h jpegcomp.h
libjpeg_la_SOURCES = $(HDRS) jcapimin.c jcapistd.c jccoefct.c jccolor.c \
jcdctmgr.c jchuff.c jcinit.c jcmainct.c jcmarker.c jcmaster.c \
jcomapi.c jcparam.c jcphuff.c jcprepct.c jcsample.c jctrans.c \
jdapimin.c jdapistd.c jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c \
jddctmgr.c jdhuff.c jdinput.c jdmainct.c jdmarker.c jdmaster.c \
jdmerge.c jdphuff.c jdpostct.c jdsample.c jdtrans.c jerror.c \
jfdctflt.c jfdctfst.c jfdctint.c jidctflt.c jidctfst.c jidctint.c \
jidctred.c jquant1.c jquant2.c jutils.c jmemmgr.c jmemnobs.c
if WITH_ARITH
libjpeg_la_SOURCES += jaricom.c
endif
if WITH_ARITH_ENC
libjpeg_la_SOURCES += jcarith.c
endif
if WITH_ARITH_DEC
libjpeg_la_SOURCES += jdarith.c
endif
libturbojpeg_la_SOURCES = $(libjpeg_la_SOURCES) turbojpegl.c turbojpeg.h \
turbojpeg-mapfile
if ANON_VERSION_SCRIPT
libturbojpeg_la_LDFLAGS += $(ANON_VERSION_SCRIPT_FLAG)$(srcdir)/turbojpeg-mapfile
endif
if VERSION_SCRIPT
libjpeg_la_LDFLAGS += $(VERSION_SCRIPT_FLAG)libjpeg.map
endif
if WITH_SIMD
SUBDIRS = simd
libjpeg_la_LIBADD = simd/libsimd.la
libturbojpeg_la_LIBADD = simd/libsimd.la
else
libjpeg_la_SOURCES += jsimd_none.c
endif
TSTHDRS = rrutil.h rrtimer.h
bin_PROGRAMS = cjpeg djpeg jpegtran rdjpgcom wrjpgcom
noinst_PROGRAMS = jpgtest jpegut
jpgtest_SOURCES = $(TSTHDRS) jpgtest.cxx bmp.h bmp.c
jpgtest_LDADD = libturbojpeg.la
jpegut_SOURCES = $(TSTHDRS) jpegut.c bmp.h bmp.c
jpegut_LDADD = libturbojpeg.la
cjpeg_SOURCES = cdjpeg.h cderror.h cdjpeg.c cjpeg.c rdbmp.c rdgif.c \
rdppm.c rdswitch.c rdtarga.c
cjpeg_LDADD = libjpeg.la
cjpeg_CFLAGS = -DBMP_SUPPORTED -DGIF_SUPPORTED -DPPM_SUPPORTED \
-DTARGA_SUPPORTED
djpeg_SOURCES = cdjpeg.h cderror.h cdjpeg.c djpeg.c rdcolmap.c rdswitch.c \
wrbmp.c wrgif.c wrppm.c wrtarga.c
djpeg_LDADD = libjpeg.la
djpeg_CFLAGS = -DBMP_SUPPORTED -DGIF_SUPPORTED -DPPM_SUPPORTED \
-DTARGA_SUPPORTED
jpegtran_SOURCES = jpegtran.c rdswitch.c cdjpeg.c transupp.c transupp.h
jpegtran_LDADD = libjpeg.la
rdjpgcom_SOURCES = rdjpgcom.c
rdjpgcom_LDADD = libjpeg.la
wrjpgcom_SOURCES = wrjpgcom.c
wrjpgcom_LDADD = libjpeg.la
dist_man1_MANS = cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 wrjpgcom.1
DOCS= README install.txt usage.txt wizard.txt example.c libjpeg.txt \
structure.txt coderules.txt filelist.txt jconfig.txt change.log \
README-turbo.txt rdrle.c wrrle.c LICENSE.txt LGPL.txt BUILDING.txt \
ChangeLog.txt
TESTFILES= testorig.jpg testorig.ppm testimg.bmp testimgflt.jpg \
testimgfst.jpg testimgint.jpg testimgp.jpg testimgflt.ppm testimgfst.ppm \
testimgint.ppm testimgflt-nosimd.jpg testimgcrop.jpg testimgari.jpg \
testimgari.ppm
EXTRA_DIST = win release $(DOCS) $(TESTFILES) CMakeLists.txt \
sharedlib/CMakeLists.txt cmakescripts libjpeg.map.in
dist-hook:
rm -rf `find $(distdir) -name .svn`
test: testclean all
./jpegut
./jpegut -yuv
./cjpeg -dct int -outfile testoutint.jpg $(srcdir)/testorig.ppm
cmp $(srcdir)/testimgint.jpg testoutint.jpg
./cjpeg -dct fast -opt -outfile testoutfst.jpg $(srcdir)/testorig.ppm
cmp $(srcdir)/testimgfst.jpg testoutfst.jpg
./cjpeg -dct float -outfile testoutflt.jpg $(srcdir)/testorig.ppm
if WITH_SIMD
cmp $(srcdir)/testimgflt.jpg testoutflt.jpg
else
cmp $(srcdir)/testimgflt-nosimd.jpg testoutflt.jpg
endif
./djpeg -dct int -fast -ppm -outfile testoutint.ppm $(srcdir)/testorig.jpg
cmp $(srcdir)/testimgint.ppm testoutint.ppm
./djpeg -dct fast -ppm -outfile testoutfst.ppm $(srcdir)/testorig.jpg
cmp $(srcdir)/testimgfst.ppm testoutfst.ppm
./djpeg -dct float -ppm -outfile testoutflt.ppm $(srcdir)/testorig.jpg
if WITH_SIMD
cmp $(srcdir)/testimgflt.ppm testoutflt.ppm
else
cmp $(srcdir)/testorig.ppm testoutflt.ppm
endif
./djpeg -dct int -bmp -colors 256 -outfile testout.bmp $(srcdir)/testorig.jpg
cmp $(srcdir)/testimg.bmp testout.bmp
if WITH_ARITH_ENC
./cjpeg -dct int -arithmetic -outfile testoutari.jpg $(srcdir)/testorig.ppm
cmp $(srcdir)/testimgari.jpg testoutari.jpg
./jpegtran -arithmetic -outfile testouta.jpg $(srcdir)/testimgint.jpg
cmp $(srcdir)/testimgari.jpg testouta.jpg
endif
if WITH_ARITH_DEC
./djpeg -dct int -fast -ppm -outfile testoutari.ppm $(srcdir)/testimgari.jpg
cmp $(srcdir)/testimgari.ppm testoutari.ppm
./jpegtran -outfile testouta.jpg $(srcdir)/testimgari.jpg
cmp $(srcdir)/testimgint.jpg testouta.jpg
endif
./cjpeg -dct int -progressive -outfile testoutp.jpg $(srcdir)/testorig.ppm
cmp $(srcdir)/testimgp.jpg testoutp.jpg
./jpegtran -outfile testoutt.jpg testoutp.jpg
cmp $(srcdir)/testimgint.jpg testoutt.jpg
./jpegtran -crop 120x90+20+50 -transpose -perfect -outfile testoutcrop.jpg $(srcdir)/testorig.jpg
cmp $(srcdir)/testimgcrop.jpg testoutcrop.jpg
testclean:
rm -f testout*
rm -f *_GRAYQ[0-9]*.bmp
rm -f *_GRAYQ[0-9]*.ppm
rm -f *_GRAYQ[0-9]*.jpg
rm -f *_420Q[0-9]*.bmp
rm -f *_420Q[0-9]*.ppm
rm -f *_420Q[0-9]*.jpg
rm -f *_422Q[0-9]*.bmp
rm -f *_422Q[0-9]*.ppm
rm -f *_422Q[0-9]*.jpg
rm -f *_444Q[0-9]*.bmp
rm -f *_444Q[0-9]*.ppm
rm -f *_444Q[0-9]*.jpg
if X86_64
install-exec-hook:
__PREFIX=`echo ${prefix} | sed -e 's@\/*$$@@'`; \
if [ "$$__PREFIX" = "/opt/libjpeg-turbo" ]; then \
cd $(DESTDIR)/${prefix}; \
if [ -d lib -a ! -d lib64 -a ! -h lib64 ]; then \
$(LN_S) lib lib64; \
fi \
fi
else
install-exec-hook:
__PREFIX=`echo ${prefix} | sed -e 's@\/*$$@@'`; \
if [ "$$__PREFIX" = "/opt/libjpeg-turbo" ]; then \
cd $(DESTDIR)/${prefix}; \
if [ -d lib -a ! -d lib32 -a ! -h lib32 ]; then \
$(LN_S) lib lib32; \
fi \
fi
endif
rpm: all
TMPDIR=`mktemp -d /tmp/${PACKAGE_NAME}-build.XXXXXX`; \
mkdir -p $$TMPDIR/RPMS; \
ln -fs `pwd` $$TMPDIR/BUILD; \
rm -f ${PACKAGE_NAME}.${RPMARCH}.rpm; \
rpmbuild -bb --define "_blddir $$TMPDIR/buildroot" \
--define "_topdir $$TMPDIR" --define "_srcdir ${srcdir}" \
--target ${RPMARCH} libjpeg-turbo.spec; \
cp $$TMPDIR/RPMS/${RPMARCH}/${PACKAGE_NAME}-${VERSION}-${BUILD}.${RPMARCH}.rpm ${PACKAGE_NAME}.${RPMARCH}.rpm; \
rm -rf $$TMPDIR
srpm: dist-gzip
TMPDIR=`mktemp -d /tmp/${PACKAGE_NAME}-build.XXXXXX`; \
mkdir -p $$TMPDIR/RPMS; \
mkdir -p $$TMPDIR/SRPMS; \
mkdir -p $$TMPDIR/BUILD; \
mkdir -p $$TMPDIR/SOURCES; \
mkdir -p $$TMPDIR/SPECS; \
rm -f ${PACKAGE_NAME}.src.rpm; \
cp ${PACKAGE_NAME}-${VERSION}.tar.gz $$TMPDIR/SOURCES; \
cat libjpeg-turbo.spec | sed s/%{_blddir}/%{_tmppath}/g \
| sed s@%{_srcdir}/@@g | sed s/#--\>//g \
>$$TMPDIR/SPECS/libjpeg-turbo.spec; \
rpmbuild -bs --define "_topdir $$TMPDIR" $$TMPDIR/SPECS/libjpeg-turbo.spec; \
cp $$TMPDIR/SRPMS/${PACKAGE_NAME}-${VERSION}-${BUILD}.src.rpm ${PACKAGE_NAME}.src.rpm; \
rm -rf $$TMPDIR
deb: all
sh $(srcdir)/release/makedpkg ${PACKAGE_NAME} ${VERSION} ${BUILD} \
${DEBARCH} ${srcdir}
if X86_64
udmg: all
sh makemacpkg universal ${BUILDDIR32}
endif
dmg: all
sh makemacpkg
if X86_64
csunpkg: all
sh makesunpkg combined ${BUILDDIR32}
endif
sunpkg: all
sh makesunpkg
cygwinpkg: all
sh $(srcdir)/release/makecygwinpkg ${PACKAGE_NAME} ${VERSION} ${srcdir}

310
README
View File

@@ -1,21 +1,20 @@
libjpeg-turbo note: This file is mostly taken from the libjpeg v8b README
file, and it is included only for reference. Some parts of it may not apply to
libjpeg-turbo. Please see README-turbo.txt for information specific to the
turbo version.
The Independent JPEG Group's JPEG software
==========================================
README for release 6a of 7-Feb-96
=================================
This distribution contains a release of the Independent JPEG Group's free JPEG
software. You are welcome to redistribute this software and to use it for any
purpose, subject to the conditions under LEGAL ISSUES, below.
This distribution contains the sixth public release of the Independent JPEG
Group's free JPEG software. You are welcome to redistribute this software and
to use it for any purpose, subject to the conditions under LEGAL ISSUES, below.
Serious users of this software (particularly those incorporating it into
larger programs) should contact IJG at jpeg-info@uunet.uu.net to be added to
our electronic mailing list. Mailing list members are notified of updates
and have a chance to participate in technical discussions, etc.
This software is the work of Tom Lane, Philip Gladstone, Luis Ortiz, Jim
Boucher, Lee Crocker, Julian Minguillon, George Phillips, Davide Rossi,
Ge' Weijers, and other members of the Independent JPEG Group.
This software is the work of Tom Lane, Guido Vollbeding, Philip Gladstone,
Bill Allombert, Jim Boucher, Lee Crocker, Bob Friesenhahn, Ben Jackson,
Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi, Ge' Weijers,
and other members of the Independent JPEG Group.
IJG is not affiliated with the official ISO JPEG standards committee.
@@ -29,27 +28,26 @@ OVERVIEW General description of JPEG and the IJG software.
LEGAL ISSUES Copyright, lack of warranty, terms of distribution.
REFERENCES Where to learn more about JPEG.
ARCHIVE LOCATIONS Where to find newer versions of this software.
RELATED SOFTWARE Other stuff you should get.
FILE FORMAT WARS Software *not* to get.
TO DO Plans for future IJG releases.
Other documentation files in the distribution are:
User documentation:
install.doc How to configure and install the IJG software.
usage.doc Usage instructions for cjpeg, djpeg, jpegtran,
install.txt How to configure and install the IJG software.
usage.txt Usage instructions for cjpeg, djpeg, jpegtran,
rdjpgcom, and wrjpgcom.
*.1 Unix-style man pages for programs (same info as usage.doc).
wizard.doc Advanced usage instructions for JPEG wizards only.
*.1 Unix-style man pages for programs (same info as usage.txt).
wizard.txt Advanced usage instructions for JPEG wizards only.
change.log Version-to-version change highlights.
Programmer and internal documentation:
libjpeg.doc How to use the JPEG library in your own programs.
libjpeg.txt How to use the JPEG library in your own programs.
example.c Sample code for calling the JPEG library.
structure.doc Overview of the JPEG library's internal structure.
filelist.doc Road map of IJG files.
coderules.doc Coding style rules --- please read if you contribute code.
structure.txt Overview of the JPEG library's internal structure.
filelist.txt Road map of IJG files.
coderules.txt Coding style rules --- please read if you contribute code.
Please read at least the files install.doc and usage.doc. Useful information
Please read at least the files install.txt and usage.txt. Some information
can also be found in the JPEG FAQ (Frequently Asked Questions) article. See
ARCHIVE LOCATIONS below to find out where to obtain the FAQ article.
@@ -61,24 +59,27 @@ the order listed) before diving into the code.
OVERVIEW
========
This package contains C software to implement JPEG image compression and
decompression. JPEG (pronounced "jay-peg") is a standardized compression
method for full-color and gray-scale images. JPEG is intended for compressing
"real-world" scenes; line drawings, cartoons and other non-realistic images
are not its strong suit. JPEG is lossy, meaning that the output image is not
exactly identical to the input image. Hence you must not use JPEG if you
have to have identical output bits. However, on typical photographic images,
very good compression levels can be obtained with no visible change, and
remarkably high compression levels are possible if you can tolerate a
low-quality image. For more details, see the references, or just experiment
with various compression settings.
This package contains C software to implement JPEG image encoding, decoding,
and transcoding. JPEG (pronounced "jay-peg") is a standardized compression
method for full-color and gray-scale images. JPEG's strong suit is compressing
photographic images or other types of images which have smooth color and
brightness transitions between neighboring pixels. Images with sharp lines or
other abrupt features may not compress well with JPEG, and a higher JPEG
quality may have to be used to avoid visible compression artifacts with such
images.
JPEG is lossy, meaning that the output pixels are not necessarily identical to
the input pixels. However, on photographic content and other "smooth" images,
very good compression ratios can be obtained with no visible compression
artifacts, and extremely high compression ratios are possible if you are
willing to sacrifice image quality (by reducing the "quality" setting in the
compressor.)
This software implements JPEG baseline, extended-sequential, and progressive
compression processes. Provision is made for supporting all variants of these
processes, although some uncommon parameter settings aren't implemented yet.
For legal reasons, we are not distributing code for the arithmetic-coding
variants of JPEG; see LEGAL ISSUES. We have made no provision for supporting
the hierarchical or lossless processes defined in the standard.
We have made no provision for supporting the hierarchical or lossless
processes defined in the standard.
We provide a set of library routines for reading and writing JPEG image files,
plus two sample applications "cjpeg" and "djpeg", which use the library to
@@ -90,10 +91,11 @@ considerable functionality beyond the bare JPEG coding/decoding capability;
for example, the color quantization modules are not strictly part of JPEG
decoding, but they are essential for output to colormapped file formats or
colormapped displays. These extra functions can be compiled out of the
library if not required for a particular application. We have also included
"jpegtran", a utility for lossless transcoding between different JPEG
processes, and "rdjpgcom" and "wrjpgcom", two simple applications for
inserting and extracting textual comments in JFIF files.
library if not required for a particular application.
We have also included "jpegtran", a utility for lossless transcoding between
different JPEG processes, and "rdjpgcom" and "wrjpgcom", two simple
applications for inserting and extracting textual comments in JFIF files.
The emphasis in designing this software has been on achieving portability and
flexibility, while also making it fast enough to be useful. In particular,
@@ -126,7 +128,7 @@ with respect to this software, its quality, accuracy, merchantability, or
fitness for a particular purpose. This software is provided "AS IS", and you,
its user, assume the entire risk as to its quality and accuracy.
This software is copyright (C) 1991-1996, Thomas G. Lane.
This software is copyright (C) 1991-2010, Thomas G. Lane, Guido Vollbeding.
All Rights Reserved except as specified below.
Permission is hereby granted to use, copy, modify, and distribute this
@@ -166,25 +168,18 @@ ansi2knr.c for full details.) However, since ansi2knr.c is not needed as part
of any program generated from the IJG code, this does not limit you more than
the foregoing paragraphs do.
The configuration script "configure" was produced with GNU Autoconf. It
is copyright by the Free Software Foundation but is freely distributable.
The Unix configuration script "configure" was produced with GNU Autoconf.
It is copyright by the Free Software Foundation but is freely distributable.
The same holds for its supporting scripts (config.guess, config.sub,
ltmain.sh). Another support script, install-sh, is copyright by X Consortium
but is also freely distributable.
It appears that the arithmetic coding option of the JPEG spec is covered by
patents owned by IBM, AT&T, and Mitsubishi. Hence arithmetic coding cannot
legally be used without obtaining one or more licenses. For this reason,
support for arithmetic coding has been removed from the free JPEG software.
(Since arithmetic coding provides only a marginal gain over the unpatented
Huffman mode, it is unlikely that very many implementations will support it.)
So far as we are aware, there are no patent restrictions on the remaining
code.
WARNING: Unisys has begun to enforce their patent on LZW compression against
GIF encoders and decoders. You will need a license from Unisys to use the
included rdgif.c or wrgif.c files in a commercial or shareware application.
At this time, Unisys is not enforcing their patent against freeware, so
distribution of this package remains legal. However, we intend to remove
GIF support from the IJG package as soon as a suitable replacement format
becomes reasonably popular.
The IJG distribution formerly included code to read and write GIF files.
To avoid entanglement with the Unisys LZW patent, GIF reading support has
been removed altogether, and the GIF writer has been simplified to produce
"uncompressed GIFs". This technique does not use the LZW algorithm; the
resulting GIF files are larger than usual, but are readable by all standard
GIF decoders.
We are required to state that
"The Graphics Interchange Format(c) is the Copyright property of
@@ -195,7 +190,7 @@ We are required to state that
REFERENCES
==========
We highly recommend reading one or more of these references before trying to
We recommend reading one or more of these references before trying to
understand the innards of the JPEG software.
The best short technical introduction to the JPEG compression algorithm is
@@ -203,181 +198,92 @@ The best short technical introduction to the JPEG compression algorithm is
Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44.
(Adjacent articles in that issue discuss MPEG motion picture compression,
applications of JPEG, and related topics.) If you don't have the CACM issue
handy, a PostScript file containing a revised version of Wallace's article
is available at ftp.uu.net, graphics/jpeg/wallace.ps.gz. The file (actually
handy, a PostScript file containing a revised version of Wallace's article is
available at http://www.ijg.org/files/wallace.ps.gz. The file (actually
a preprint for an article that appeared in IEEE Trans. Consumer Electronics)
omits the sample images that appeared in CACM, but it includes corrections
and some added material. Note: the Wallace article is copyright ACM and
IEEE, and it may not be used for commercial purposes.
and some added material. Note: the Wallace article is copyright ACM and IEEE,
and it may not be used for commercial purposes.
A somewhat less technical, more leisurely introduction to JPEG can be found in
"The Data Compression Book" by Mark Nelson, published by M&T Books (Redwood
City, CA), 1991, ISBN 1-55851-216-0. This book provides good explanations and
example C code for a multitude of compression methods including JPEG. It is
an excellent source if you are comfortable reading C code but don't know much
about data compression in general. The book's JPEG sample code is far from
industrial-strength, but when you are ready to look at a full implementation,
you've got one here...
"The Data Compression Book" by Mark Nelson and Jean-loup Gailly, published by
M&T Books (New York), 2nd ed. 1996, ISBN 1-55851-434-1. This book provides
good explanations and example C code for a multitude of compression methods
including JPEG. It is an excellent source if you are comfortable reading C
code but don't know much about data compression in general. The book's JPEG
sample code is far from industrial-strength, but when you are ready to look
at a full implementation, you've got one here...
The best full description of JPEG is the textbook "JPEG Still Image Data
Compression Standard" by William B. Pennebaker and Joan L. Mitchell, published
by Van Nostrand Reinhold, 1993, ISBN 0-442-01272-1. Price US$59.95, 638 pp.
The book includes the complete text of the ISO JPEG standards (DIS 10918-1
and draft DIS 10918-2). This is by far the most complete exposition of JPEG
in existence, and we highly recommend it.
The best currently available description of JPEG is the textbook "JPEG Still
Image Data Compression Standard" by William B. Pennebaker and Joan L.
Mitchell, published by Van Nostrand Reinhold, 1993, ISBN 0-442-01272-1.
Price US$59.95, 638 pp. The book includes the complete text of the ISO JPEG
standards (DIS 10918-1 and draft DIS 10918-2).
The JPEG standard itself is not available electronically; you must order a
paper copy through ISO or ITU. (Unless you feel a need to own a certified
official copy, we recommend buying the Pennebaker and Mitchell book instead;
it's much cheaper and includes a great deal of useful explanatory material.)
In the USA, copies of the standard may be ordered from ANSI Sales at (212)
642-4900, or from Global Engineering Documents at (800) 854-7179. (ANSI
doesn't take credit card orders, but Global does.) It's not cheap: as of
1992, ANSI was charging $95 for Part 1 and $47 for Part 2, plus 7%
shipping/handling. The standard is divided into two parts, Part 1 being the
actual specification, while Part 2 covers compliance testing methods. Part 1
is titled "Digital Compression and Coding of Continuous-tone Still Images,
The original JPEG standard is divided into two parts, Part 1 being the actual
specification, while Part 2 covers compliance testing methods. Part 1 is
titled "Digital Compression and Coding of Continuous-tone Still Images,
Part 1: Requirements and guidelines" and has document numbers ISO/IEC IS
10918-1, ITU-T T.81. Part 2 is titled "Digital Compression and Coding of
Continuous-tone Still Images, Part 2: Compliance testing" and has document
numbers ISO/IEC IS 10918-2, ITU-T T.83.
Extensions to the original JPEG standard are defined in JPEG Part 3, a new ISO
document. Part 3 is undergoing ISO balloting and is expected to be approved
by the end of 1995; it will have document numbers ISO/IEC IS 10918-3, ITU-T
T.84. IJG currently does not support any Part 3 extensions.
The JPEG standard does not specify all details of an interchangeable file
format. For the omitted details we follow the "JFIF" conventions, revision
1.02. A copy of the JFIF spec is available from:
Literature Department
C-Cube Microsystems, Inc.
1778 McCarthy Blvd.
Milpitas, CA 95035
phone (408) 944-6300, fax (408) 944-6314
A PostScript version of this document is available at ftp.uu.net, file
graphics/jpeg/jfif.ps.gz. It can also be obtained by e-mail from the C-Cube
mail server, netlib@c3.pla.ca.us. Send the message "send jfif_ps from jpeg"
to the server to obtain the JFIF document; send the message "help" if you have
trouble.
1.02. JFIF 1.02 has been adopted as an Ecma International Technical Report
and thus received a formal publication status. It is available as a free
download in PDF format from
http://www.ecma-international.org/publications/techreports/E-TR-098.htm.
A PostScript version of the JFIF document is available at
http://www.ijg.org/files/jfif.ps.gz. There is also a plain text version at
http://www.ijg.org/files/jfif.txt.gz, but it is missing the figures.
The TIFF 6.0 file format specification can be obtained by FTP from sgi.com
(192.48.153.1), file graphics/tiff/TIFF6.ps.Z; or you can order a printed
copy from Aldus Corp. at (206) 628-6593. The JPEG incorporation scheme
The TIFF 6.0 file format specification can be obtained by FTP from
ftp://ftp.sgi.com/graphics/tiff/TIFF6.ps.gz. The JPEG incorporation scheme
found in the TIFF 6.0 spec of 3-June-92 has a number of serious problems.
IJG does not recommend use of the TIFF 6.0 design (TIFF Compression tag 6).
Instead, we recommend the JPEG design proposed by TIFF Technical Note #2
(Compression tag 7). Copies of this Note can be obtained from sgi.com or
from ftp.uu.net:/graphics/jpeg/. It is expected that the next revision of
the TIFF spec will replace the 6.0 JPEG design with the Note's design.
(Compression tag 7). Copies of this Note can be obtained from
http://www.ijg.org/files/. It is expected that the next revision
of the TIFF spec will replace the 6.0 JPEG design with the Note's design.
Although IJG's own code does not support TIFF/JPEG, the free libtiff library
uses our library to implement TIFF/JPEG per the Note. libtiff is available
from sgi.com:/graphics/tiff/.
uses our library to implement TIFF/JPEG per the Note.
ARCHIVE LOCATIONS
=================
The "official" archive site for this software is ftp.uu.net (Internet
address 192.48.96.9). The most recent released version can always be found
there in directory graphics/jpeg. This particular version will be archived
as graphics/jpeg/jpegsrc.v6a.tar.gz. If you are on the Internet, you
can retrieve files from ftp.uu.net by standard anonymous FTP. If you don't
have FTP access, UUNET's archives are also available via UUCP; contact
help@uunet.uu.net for information on retrieving files that way.
The "official" archive site for this software is www.ijg.org.
The most recent released version can always be found there in
directory "files". This particular version will be archived as
http://www.ijg.org/files/jpegsrc.v8b.tar.gz, and in Windows-compatible
"zip" archive format as http://www.ijg.org/files/jpegsr8b.zip.
Numerous Internet sites maintain copies of the UUNET files. However, only
ftp.uu.net is guaranteed to have the latest official version.
You can also obtain this software in DOS-compatible "zip" archive format from
the SimTel archives (ftp.coast.net:/SimTel/msdos/graphics/), or on CompuServe
in the Graphics Support forum (GO CIS:GRAPHSUP), library 12 "JPEG Tools".
Again, these versions may sometimes lag behind the ftp.uu.net release.
The JPEG FAQ (Frequently Asked Questions) article is a useful source of
general information about JPEG. It is updated constantly and therefore is
not included in this distribution. The FAQ is posted every two weeks to
Usenet newsgroups comp.graphics.misc, news.answers, and other groups.
You can always obtain the latest version from the news.answers archive at
rtfm.mit.edu. By FTP, fetch /pub/usenet/news.answers/jpeg-faq/part1 and
.../part2. If you don't have FTP, send e-mail to mail-server@rtfm.mit.edu
The JPEG FAQ (Frequently Asked Questions) article is a source of some
general information about JPEG.
It is available on the World Wide Web at http://www.faqs.org/faqs/jpeg-faq/
and other news.answers archive sites, including the official news.answers
archive at rtfm.mit.edu: ftp://rtfm.mit.edu/pub/usenet/news.answers/jpeg-faq/.
If you don't have Web or FTP access, send e-mail to mail-server@rtfm.mit.edu
with body
send usenet/news.answers/jpeg-faq/part1
send usenet/news.answers/jpeg-faq/part2
RELATED SOFTWARE
================
Numerous viewing and image manipulation programs now support JPEG. (Quite a
few of them use this library to do so.) The JPEG FAQ described above lists
some of the more popular free and shareware viewers, and tells where to
obtain them on Internet.
If you are on a Unix machine, we highly recommend Jef Poskanzer's free
PBMPLUS image software, which provides many useful operations on PPM-format
image files. In particular, it can convert PPM images to and from a wide
range of other formats. You can obtain this package by FTP from ftp.x.org
(contrib/pbmplus*.tar.Z) or ftp.ee.lbl.gov (pbmplus*.tar.Z). There is also
a newer update of this package called NETPBM, available from
wuarchive.wustl.edu under directory /graphics/graphics/packages/NetPBM/.
Unfortunately PBMPLUS/NETPBM is not nearly as portable as the IJG software
is; you are likely to have difficulty making it work on any non-Unix machine.
A different free JPEG implementation, written by the PVRG group at Stanford,
is available from havefun.stanford.edu in directory pub/jpeg. This program
is designed for research and experimentation rather than production use;
it is slower, harder to use, and less portable than the IJG code, but it
is easier to read and modify. Also, the PVRG code supports lossless JPEG,
which we do not.
FILE FORMAT WARS
================
Some JPEG programs produce files that are not compatible with our library.
The root of the problem is that the ISO JPEG committee failed to specify a
concrete file format. Some vendors "filled in the blanks" on their own,
creating proprietary formats that no one else could read. (For example, none
of the early commercial JPEG implementations for the Macintosh were able to
exchange compressed files.)
The file format we have adopted is called JFIF (see REFERENCES). This format
has been agreed to by a number of major commercial JPEG vendors, and it has
become the de facto standard. JFIF is a minimal or "low end" representation.
We recommend the use of TIFF/JPEG (TIFF revision 6.0 as modified by TIFF
Technical Note #2) for "high end" applications that need to record a lot of
additional data about an image. TIFF/JPEG is fairly new and not yet widely
supported, unfortunately.
The upcoming JPEG Part 3 standard defines a file format called SPIFF.
SPIFF is interoperable with JFIF, in the sense that most JFIF decoders should
be able to read the most common variant of SPIFF. SPIFF has some technical
advantages over JFIF, but its major claim to fame is simply that it is an
official standard rather than an informal one. At this point it is unclear
whether SPIFF will supersede JFIF or whether JFIF will remain the de-facto
standard. IJG intends to support SPIFF once the standard is frozen, but we
have not decided whether it should become our default output format or not.
(In any case, our decoder will remain capable of reading JFIF indefinitely.)
Various proprietary file formats incorporating JPEG compression also exist.
We have little or no sympathy for the existence of these formats. Indeed,
The ISO JPEG standards committee actually promotes different formats like
"JPEG 2000" or "JPEG XR" which are incompatible with original DCT-based
JPEG. IJG therefore does not support these formats (see REFERENCES). Indeed,
one of the original reasons for developing this free software was to help
force convergence on common, open format standards for JPEG files. Don't
use a proprietary file format!
force convergence on common, interoperable format standards for JPEG files.
Don't use an incompatible file format!
(In any case, our decoder will remain capable of reading existing JPEG
image files indefinitely.)
TO DO
=====
In future versions, we are considering supporting some of the upcoming JPEG
Part 3 extensions --- principally, variable quantization and the SPIFF file
format.
Tuning the software for better behavior at low quality/high compression
settings is also of interest. The current method for scaling the
quantization tables is known not to be very good at low Q values.
As always, speeding things up is high on our priority list.
Please send bug reports, offers of help, etc. to jpeg-info@uunet.uu.net.
Please send bug reports, offers of help, etc. to jpeg-info@uc.ag.

274
README-turbo.txt Executable file
View File

@@ -0,0 +1,274 @@
*******************************************************************************
** Background
*******************************************************************************
libjpeg-turbo is a high-speed version of libjpeg for x86 and x86-64 processors
which uses SIMD instructions (MMX, SSE2, etc.) to accelerate baseline JPEG
compression and decompression. libjpeg-turbo is generally 2-4x as fast
as the unmodified version of libjpeg, all else being equal.
libjpeg-turbo was originally based on libjpeg/SIMD by Miyasaka Masaru, but
the TigerVNC and VirtualGL projects made numerous enhancements to the codec,
including improved support for Mac OS X, 64-bit support, support for 32-bit
and big endian pixel formats, accelerated Huffman encoding/decoding, and
various bug fixes. The goal was to produce a fully open source codec that
could replace the partially closed source TurboJPEG/IPP codec used by VirtualGL
and TurboVNC. libjpeg-turbo generally performs in the range of 80-120% of
TurboJPEG/IPP. It is faster in some areas but slower in others.
It was decided to split libjpeg-turbo into a separate SDK so that other
projects could take advantage of this technology. The libjpeg-turbo shared
libraries can be used as drop-in replacements for libjpeg on most systems.
*******************************************************************************
** License
*******************************************************************************
Some of the optimizations to the Huffman encoder (jchuff.c) and decoder
(jdhuff.c) were borrowed from VirtualGL, and thus any distribution of
libjpeg-turbo which includes those optimizations must, as a whole, be subject
to the terms of the wxWindows Library Licence, Version 3.1. A copy of this
license can be found in this directory under LICENSE.txt. The wxWindows
Library License is based on the LGPL but includes provisions which allow the
Library to be statically linked into proprietary libraries and applications
without requiring the resulting binaries to be distributed under the terms of
the LGPL.
The rest of the source code, apart from the Huffman codec optimizations, falls
under a less restrictive, BSD-style license (see README.) You can choose to
distribute libjpeg-turbo, as a whole, under this BSD-style license by simply
replacing the optimized jchuff.c and jdhuff.c with their unoptimized
counterparts from the libjpeg v6b source.
*******************************************************************************
** Using libjpeg-turbo
*******************************************************************************
=============================
Replacing libjpeg at Run Time
=============================
If a Unix application is dynamically linked with libjpeg, then you can replace
libjpeg with libjpeg-turbo at run time by manipulating the LD_LIBRARY_PATH.
For instance:
[Using libjpeg]
> time cjpeg <vgl_5674_0098.ppm >vgl_5674_0098.jpg
real 0m0.392s
user 0m0.074s
sys 0m0.020s
[Using libjpeg-turbo]
> export LD_LIBRARY_PATH=/opt/libjpeg-turbo/{lib}:$LD_LIBRARY_PATH
> time cjpeg <vgl_5674_0098.ppm >vgl_5674_0098.jpg
real 0m0.109s
user 0m0.029s
sys 0m0.010s
NOTE: {lib} can be lib, lib32, lib64, or lib/64, depending on the O/S and
architecture.
System administrators can also replace the libjpeg sym links in /usr/{lib} with
links to the libjpeg dynamic library located in /opt/libjpeg-turbo/{lib}. This
will effectively accelerate every dynamically linked libjpeg application on the
system.
The Windows distribution of the libjpeg-turbo SDK installs the libjpeg-turbo
DLL (jpeg62.dll, jpeg7.dll, or jpeg8.dll, depending on whether libjpeg v6b,
v7, or v8 emulation is enabled) into c:\libjpeg-turbo[64]\bin, and the PATH
environment variable can be modified such that this directory is searched
before any others that might contain a libjpeg DLL. However, if a libjpeg
DLL exists in an application's install directory, then Windows will load this
DLL first whenever the application is launched. Thus, if an application ships
with jpeg62.dll, jpeg7.dll, or jpeg8.dll, then back up the application's
version of this DLL and copy c:\libjpeg-turbo\bin\jpeg*.dll into the
application's install directory to accelerate it.
The version of the libjpeg-turbo DLL distributed with the "official"
libjpeg-turbo SDK requires the Visual C++ 2008 C run time DLL (msvcr90.dll).
msvcr90.dll ships with more recent versions of Windows, but users of older
Windows releases can obtain it from the Visual C++ 2008 Redistributable
Package, which is available as a free download from Microsoft's web site.
NOTE: Features of libjpeg which require passing a C run time structure, such
as a file handle, from an application to libjpeg will probably not work with
the "official" version of the libjpeg-turbo DLL unless the application is also
built to use the Visual C++ 2008 C run time DLL. In particular, this affects
jpeg_stdio_dest() and jpeg_stdio_src().
Mac applications typically embed their own copies of the libjpeg dylib inside
the (hidden) application bundle, so it is not possible to globally replace
libjpeg on OS X systems. If an application uses a shared library version of
libjpeg, then it may be possible to replace the application's version of it.
This would generally involve copying libjpeg.*.dylib from libjpeg-turbo into
the appropriate place in the application bundle and using install_name_tool to
repoint the dylib to the new directory. This requires an advanced knowledge of
OS X and would not survive an upgrade or a re-install of the application.
Thus, it is not recommended for most users.
=======================
Replacing TurboJPEG/IPP
=======================
libjpeg-turbo is a drop-in replacement for the TurboJPEG/IPP SDK used by
VirtualGL 2.1.x and TurboVNC 0.6 (and prior.) libjpeg-turbo contains a wrapper
library (TurboJPEG/OSS) that emulates the TurboJPEG API using libjpeg-turbo
instead of the closed source Intel Performance Primitives. You can replace the
TurboJPEG/IPP package on Linux systems with the libjpeg-turbo package in order
to make existing releases of VirtualGL 2.1.x and TurboVNC use the new codec at
run time. Note that the 64-bit libjpeg-turbo packages contain only 64-bit
binaries, whereas the TurboJPEG/IPP 64-bit packages contained both 64-bit and
32-bit binaries. Thus, to replace a TurboJPEG/IPP 64-bit package, install
both the 64-bit and 32-bit versions of libjpeg-turbo.
You can also build the VirtualGL 2.1.x and TurboVNC 0.6 source code with
the libjpeg-turbo SDK instead of TurboJPEG/IPP. It should work identically.
libjpeg-turbo also includes static library versions of TurboJPEG/OSS, which
are used to build TurboVNC 1.0 and later.
========================================
Using libjpeg-turbo in Your Own Programs
========================================
For the most part, libjpeg-turbo should work identically to libjpeg, so in
most cases, an application can be built against libjpeg and then run against
libjpeg-turbo. On Unix systems (including Cygwin), you can build against
libjpeg-turbo instead of libjpeg by setting
CPATH=/opt/libjpeg-turbo/include
and
LIBRARY_PATH=/opt/libjpeg-turbo/{lib}
({lib} = lib32 or lib64, depending on whether you are building a 32-bit or a
64-bit application.)
If using MinGW, then set
CPATH=/c/libjpeg-turbo-gcc[64]/include
and
LIBRARY_PATH=/c/libjpeg-turbo-gcc[64]/lib
Building against libjpeg-turbo is useful, for instance, if you want to build an
application that leverages the libjpeg-turbo colorspace extensions (see below.)
On Linux and Solaris systems, you would still need to manipulate the
LD_LIBRARY_PATH or sym links appropriately to use libjpeg-turbo at run time.
On such systems, you can pass -R /opt/libjpeg-turbo/{lib} to the linker to
force the use of libjpeg-turbo at run time rather than libjpeg (also useful if
you want to leverage the colorspace extensions), or you can link against the
libjpeg-turbo static library.
To force a Linux, Solaris, or MinGW application to link against the static
version of libjpeg-turbo, you can use the following linker options:
-Wl,-Bstatic -ljpeg -Wl,-Bdynamic
On OS X, simply add /opt/libjpeg-turbo/lib/libjpeg.a to the linker command
line (this also works on Linux and Solaris.)
To build Visual C++ applications using libjpeg-turbo, add
c:\libjpeg-turbo[64]\include to your system or user INCLUDE environment
variable and c:\libjpeg-turbo[64]\lib to your system or user LIB environment
variable, and then link against either jpeg.lib (to use the DLL version of
libjpeg-turbo) or jpeg-static.lib (to use the static version of libjpeg-turbo.)
=====================
Colorspace Extensions
=====================
libjpeg-turbo includes extensions which allow JPEG images to be compressed
directly from (and decompressed directly to) buffers which use BGR, BGRX,
RGBX, XBGR, and XRGB pixel ordering. This is implemented with six new
colorspace constants:
JCS_EXT_RGB /* red/green/blue */
JCS_EXT_RGBX /* red/green/blue/x */
JCS_EXT_BGR /* blue/green/red */
JCS_EXT_BGRX /* blue/green/red/x */
JCS_EXT_XBGR /* x/blue/green/red */
JCS_EXT_XRGB /* x/red/green/blue */
Setting cinfo.in_color_space (compression) or cinfo.out_color_space
(decompression) to one of these values will cause libjpeg-turbo to read the
red, green, and blue values from (or write them to) the appropriate position in
the pixel when YUV conversion is performed.
Your application can check for the existence of these extensions at compile
time with:
#ifdef JCS_EXTENSIONS
At run time, attempting to use these extensions with a version of libjpeg
that doesn't support them will result in a "Bogus input colorspace" error.
=================================
libjpeg v7 and v8 API/ABI support
=================================
libjpeg v7 and v8 added new features to the API/ABI, and, unfortunately, the
compression and decompression structures were extended in a backward-
incompatible manner to accommodate these features. Thus, programs which are
built to use libjpeg v7 or v8 did not work with libjpeg-turbo, since it is
based on the libjpeg v6b code base. Although libjpeg v7 and v8 are still not
as widely used as v6b, enough programs (including a few Linux distros) have
made the switch that it was desirable to provide support for the libjpeg v7/v8
API/ABI in libjpeg-turbo.
Some of the libjpeg v7 and v8 features -- DCT scaling, to name one -- involve
deep modifications to the code which cannot be accommodated by libjpeg-turbo
without either breaking compatibility with libjpeg v6b or producing an
unsupportable mess. In order to fully support libjpeg v8 with all of its
features, we would have to essentially port the SIMD extensions to the libjpeg
v8 code base and maintain two separate code trees. We are hesitant to do this
until/unless the newer libjpeg code bases garner more community support and
involvement and until/unless we have some notion of whether future libjpeg
releases will also be backward-incompatible.
By passing an argument of --with-jpeg7 or --with-jpeg8 to configure, or an
argument of -DWITH_JPEG7=1 or -DWITH_JPEG8=1 to cmake, you can build a version
of libjpeg-turbo which emulates the libjpeg v7 or v8b API/ABI, so that programs
which are built against libjpeg v7 or v8 can be run with libjpeg-turbo. The
following section describes which libjpeg v7+ features are supported and which
aren't.
libjpeg v7 and v8 Features:
---------------------------
Fully supported:
-- cjpeg: Separate quality settings for luminance and chrominance
Note that the libpjeg v7+ API was extended to accommodate this feature only
for convenience purposes. It has always been possible to implement this
feature with libjpeg v6b (see rdswitch.c for an example.)
-- cjpeg: 32-bit BMP support
-- jpegtran: lossless cropping
-- jpegtran: -perfect option
-- rdjpgcom: -raw option
-- rdjpgcom: locale awareness
Fully supported when using libjpeg v7/v8 emulation:
-- libjpeg: In-memory source and destination managers
Not supported:
-- libjpeg: DCT scaling in compressor
cinfo.scale_num and cinfo.scale_denom are silently ignored.
-- libjpeg: IDCT scaling extensions in decompressor
libjpeg-turbo still supports IDCT scaling with scaling factors of 1/2, 1/4,
and 1/8 (same as libjpeg v6b.)
-- libjpeg: Fancy downsampling in compressor
cinfo.do_fancy_downsampling is silently ignored.
-- jpegtran: Scaling
Seems to depend on the DCT scaling feature, which isn't supported.

136
acinclude.m4 Normal file
View File

@@ -0,0 +1,136 @@
# AC_PROG_NASM
# --------------------------
# Check that NASM exists and determine flags
AC_DEFUN([AC_PROG_NASM],[
AC_CHECK_PROGS(NASM, [nasm nasmw])
test -z "$NASM" && AC_MSG_ERROR([no nasm (Netwide Assembler) found])
AC_MSG_CHECKING([for object file format of host system])
case "$host_os" in
cygwin* | mingw* | pw32* | interix*)
case "$host_cpu" in
x86_64)
objfmt='Win64-COFF'
;;
*)
objfmt='Win32-COFF'
;;
esac
;;
msdosdjgpp* | go32*)
objfmt='COFF'
;;
os2-emx*) # not tested
objfmt='MSOMF' # obj
;;
linux*coff* | linux*oldld*)
objfmt='COFF' # ???
;;
linux*aout*)
objfmt='a.out'
;;
linux*)
case "$host_cpu" in
x86_64)
objfmt='ELF64'
;;
*)
objfmt='ELF'
;;
esac
;;
freebsd* | netbsd* | openbsd*)
if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
objfmt='BSD-a.out'
else
case "$host_cpu" in
x86_64 | amd64)
objfmt='ELF64'
;;
*)
objfmt='ELF'
;;
esac
fi
;;
solaris* | sunos* | sysv* | sco*)
case "$host_cpu" in
x86_64)
objfmt='ELF64'
;;
*)
objfmt='ELF'
;;
esac
;;
darwin* | rhapsody* | nextstep* | openstep* | macos*)
case "$host_cpu" in
x86_64)
objfmt='Mach-O64'
;;
*)
objfmt='Mach-O'
;;
esac
;;
*)
objfmt='ELF ?'
;;
esac
AC_MSG_RESULT([$objfmt])
if test "$objfmt" = 'ELF ?'; then
objfmt='ELF'
AC_MSG_WARN([unexpected host system. assumed that the format is $objfmt.])
fi
AC_MSG_CHECKING([for object file format specifier (NAFLAGS) ])
case "$objfmt" in
MSOMF) NAFLAGS='-fobj -DOBJ32';;
Win32-COFF) NAFLAGS='-fwin32 -DWIN32';;
Win64-COFF) NAFLAGS='-fwin64 -DWIN64 -D__x86_64__';;
COFF) NAFLAGS='-fcoff -DCOFF';;
a.out) NAFLAGS='-faout -DAOUT';;
BSD-a.out) NAFLAGS='-faoutb -DAOUT';;
ELF) NAFLAGS='-felf -DELF';;
ELF64) NAFLAGS='-felf64 -DELF -D__x86_64__';;
RDF) NAFLAGS='-frdf -DRDF';;
Mach-O) NAFLAGS='-fmacho -DMACHO';;
Mach-O64) NAFLAGS='-fmacho64 -DMACHO -D__x86_64__';;
esac
AC_MSG_RESULT([$NAFLAGS])
AC_SUBST([NAFLAGS])
AC_MSG_CHECKING([whether the assembler ($NASM $NAFLAGS) works])
cat > conftest.asm <<EOF
[%line __oline__ "configure"
section .text
global _main,main
_main:
main: xor eax,eax
ret
]EOF
try_nasm='$NASM $NAFLAGS -o conftest.o conftest.asm'
if AC_TRY_EVAL(try_nasm) && test -s conftest.o; then
AC_MSG_RESULT(yes)
else
echo "configure: failed program was:" >&AC_FD_CC
cat conftest.asm >&AC_FD_CC
rm -rf conftest*
AC_MSG_RESULT(no)
AC_MSG_ERROR([installation or configuration problem: assembler cannot create object files.])
fi
AC_MSG_CHECKING([whether the linker accepts assembler output])
try_nasm='${CC-cc} -o conftest${ac_exeext} $LDFLAGS conftest.o $LIBS 1>&AC_FD_CC'
if AC_TRY_EVAL(try_nasm) && test -s conftest${ac_exeext}; then
rm -rf conftest*
AC_MSG_RESULT(yes)
else
rm -rf conftest*
AC_MSG_RESULT(no)
AC_MSG_ERROR([configuration problem: maybe object file format mismatch.])
fi
])

View File

@@ -1,36 +0,0 @@
.TH ANSI2KNR 1 "19 Jan 1996"
.SH NAME
ansi2knr \- convert ANSI C to Kernighan & Ritchie C
.SH SYNOPSIS
.I ansi2knr
[--varargs] input_file [output_file]
.SH DESCRIPTION
If no output_file is supplied, output goes to stdout.
.br
There are no error messages.
.sp
.I ansi2knr
recognizes function definitions by seeing a non-keyword identifier at the left
margin, followed by a left parenthesis, with a right parenthesis as the last
character on the line, and with a left brace as the first token on the
following line (ignoring possible intervening comments). It will recognize a
multi-line header provided that no intervening line ends with a left or right
brace or a semicolon. These algorithms ignore whitespace and comments, except
that the function name must be the first thing on the line.
.sp
The following constructs will confuse it:
.br
- Any other construct that starts at the left margin and follows the
above syntax (such as a macro or function call).
.br
- Some macros that tinker with the syntax of the function header.
.sp
The --varargs switch is obsolete, and is recognized only for
backwards compatibility. The present version of
.I ansi2knr
will always attempt to convert a ... argument to va_alist and va_dcl.
.SH AUTHOR
L. Peter Deutsch <ghost@aladdin.com> wrote the original ansi2knr and
continues to maintain the current version; most of the code in the current
version is his work. ansi2knr also includes contributions by Francois
Pinard <pinard@iro.umontreal.ca> and Jim Avera <jima@netcom.com>.

View File

@@ -1,693 +0,0 @@
/* ansi2knr.c */
/* Convert ANSI C function definitions to K&R ("traditional C") syntax */
/*
ansi2knr is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY. No author or distributor accepts responsibility to anyone for the
consequences of using it or for whether it serves any particular purpose or
works at all, unless he says so in writing. Refer to the GNU General Public
License (the "GPL") for full details.
Everyone is granted permission to copy, modify and redistribute ansi2knr,
but only under the conditions described in the GPL. A copy of this license
is supposed to have been given to you along with ansi2knr so you can know
your rights and responsibilities. It should be in a file named COPYLEFT.
[In the IJG distribution, the GPL appears below, not in a separate file.]
Among other things, the copyright notice and this notice must be preserved
on all copies.
We explicitly state here what we believe is already implied by the GPL: if
the ansi2knr program is distributed as a separate set of sources and a
separate executable file which are aggregated on a storage medium together
with another program, this in itself does not bring the other program under
the GPL, nor does the mere fact that such a program or the procedures for
constructing it invoke the ansi2knr executable bring any other part of the
program under the GPL.
*/
/*
---------- Here is the GNU GPL file COPYLEFT, referred to above ----------
----- These terms do NOT apply to the JPEG software itself; see README ------
GHOSTSCRIPT GENERAL PUBLIC LICENSE
(Clarified 11 Feb 1988)
Copyright (C) 1988 Richard M. Stallman
Everyone is permitted to copy and distribute verbatim copies of this
license, but changing it is not allowed. You can also use this wording
to make the terms for other programs.
The license agreements of most software companies keep you at the
mercy of those companies. By contrast, our general public license is
intended to give everyone the right to share Ghostscript. To make sure
that you get the rights we want you to have, we need to make
restrictions that forbid anyone to deny you these rights or to ask you
to surrender the rights. Hence this license agreement.
Specifically, we want to make sure that you have the right to give
away copies of Ghostscript, that you receive source code or else can get
it if you want it, that you can change Ghostscript or use pieces of it
in new free programs, and that you know you can do these things.
To make sure that everyone has such rights, we have to forbid you to
deprive anyone else of these rights. For example, if you distribute
copies of Ghostscript, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must tell them their rights.
Also, for our own protection, we must make certain that everyone finds
out that there is no warranty for Ghostscript. If Ghostscript is
modified by someone else and passed on, we want its recipients to know
that what they have is not what we distributed, so that any problems
introduced by others will not reflect on our reputation.
Therefore we (Richard M. Stallman and the Free Software Foundation,
Inc.) make the following terms which say what you must do to be allowed
to distribute or change Ghostscript.
COPYING POLICIES
1. You may copy and distribute verbatim copies of Ghostscript source
code as you receive it, in any medium, provided that you conspicuously
and appropriately publish on each copy a valid copyright and license
notice "Copyright (C) 1989 Aladdin Enterprises. All rights reserved.
Distributed by Free Software Foundation, Inc." (or with whatever year is
appropriate); keep intact the notices on all files that refer to this
License Agreement and to the absence of any warranty; and give any other
recipients of the Ghostscript program a copy of this License Agreement
along with the program. You may charge a distribution fee for the
physical act of transferring a copy.
2. You may modify your copy or copies of Ghostscript or any portion of
it, and copy and distribute such modifications under the terms of
Paragraph 1 above, provided that you also do the following:
a) cause the modified files to carry prominent notices stating
that you changed the files and the date of any change; and
b) cause the whole of any work that you distribute or publish,
that in whole or in part contains or is a derivative of Ghostscript
or any part thereof, to be licensed at no charge to all third
parties on terms identical to those contained in this License
Agreement (except that you may choose to grant more extensive
warranty protection to some or all third parties, at your option).
c) You may charge a distribution fee for the physical act of
transferring a copy, and you may at your option offer warranty
protection in exchange for a fee.
Mere aggregation of another unrelated program with this program (or its
derivative) on a volume of a storage or distribution medium does not bring
the other program under the scope of these terms.
3. You may copy and distribute Ghostscript (or a portion or derivative
of it, under Paragraph 2) in object code or executable form under the
terms of Paragraphs 1 and 2 above provided that you also do one of the
following:
a) accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of
Paragraphs 1 and 2 above; or,
b) accompany it with a written offer, valid for at least three
years, to give any third party free (except for a nominal
shipping charge) a complete machine-readable copy of the
corresponding source code, to be distributed under the terms of
Paragraphs 1 and 2 above; or,
c) accompany it with the information you received as to where the
corresponding source code may be obtained. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form alone.)
For an executable file, complete source code means all the source code for
all modules it contains; but, as a special exception, it need not include
source code for modules which are standard libraries that accompany the
operating system on which the executable file runs.
4. You may not copy, sublicense, distribute or transfer Ghostscript
except as expressly provided under this License Agreement. Any attempt
otherwise to copy, sublicense, distribute or transfer Ghostscript is
void and your rights to use the program under this License agreement
shall be automatically terminated. However, parties who have received
computer software programs from you with this License Agreement will not
have their licenses terminated so long as such parties remain in full
compliance.
5. If you wish to incorporate parts of Ghostscript into other free
programs whose distribution conditions are different, write to the Free
Software Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not
yet worked out a simple rule that can be stated here, but we will often
permit this. We will be guided by the two goals of preserving the free
status of all derivatives of our free software and of promoting the
sharing and reuse of software.
Your comments and suggestions about our licensing policies and our
software are welcome! Please contact the Free Software Foundation,
Inc., 675 Mass Ave, Cambridge, MA 02139, or call (617) 876-3296.
NO WARRANTY
BECAUSE GHOSTSCRIPT IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT
WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, RICHARD
M. STALLMAN, ALADDIN ENTERPRISES, L. PETER DEUTSCH, AND/OR OTHER PARTIES
PROVIDE GHOSTSCRIPT "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF GHOSTSCRIPT IS WITH
YOU. SHOULD GHOSTSCRIPT PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
NECESSARY SERVICING, REPAIR OR CORRECTION.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., L. PETER DEUTSCH, ALADDIN
ENTERPRISES, AND/OR ANY OTHER PARTY WHO MAY MODIFY AND REDISTRIBUTE
GHOSTSCRIPT AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING
ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A FAILURE OF THE
PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) GHOSTSCRIPT, EVEN IF YOU
HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR ANY CLAIM
BY ANY OTHER PARTY.
-------------------- End of file COPYLEFT ------------------------------
*/
/*
* Usage:
ansi2knr input_file [output_file]
* If no output_file is supplied, output goes to stdout.
* There are no error messages.
*
* ansi2knr recognizes function definitions by seeing a non-keyword
* identifier at the left margin, followed by a left parenthesis,
* with a right parenthesis as the last character on the line,
* and with a left brace as the first token on the following line
* (ignoring possible intervening comments).
* It will recognize a multi-line header provided that no intervening
* line ends with a left or right brace or a semicolon.
* These algorithms ignore whitespace and comments, except that
* the function name must be the first thing on the line.
* The following constructs will confuse it:
* - Any other construct that starts at the left margin and
* follows the above syntax (such as a macro or function call).
* - Some macros that tinker with the syntax of the function header.
*/
/*
* The original and principal author of ansi2knr is L. Peter Deutsch
* <ghost@aladdin.com>. Other authors are noted in the change history
* that follows (in reverse chronological order):
lpd 96-01-21 added code to cope with not HAVE_CONFIG_H and with
compilers that don't understand void, as suggested by
Tom Lane
lpd 96-01-15 changed to require that the first non-comment token
on the line following a function header be a left brace,
to reduce sensitivity to macros, as suggested by Tom Lane
<tgl@sss.pgh.pa.us>
lpd 95-06-22 removed #ifndefs whose sole purpose was to define
undefined preprocessor symbols as 0; changed all #ifdefs
for configuration symbols to #ifs
lpd 95-04-05 changed copyright notice to make it clear that
including ansi2knr in a program does not bring the entire
program under the GPL
lpd 94-12-18 added conditionals for systems where ctype macros
don't handle 8-bit characters properly, suggested by
Francois Pinard <pinard@iro.umontreal.ca>;
removed --varargs switch (this is now the default)
lpd 94-10-10 removed CONFIG_BROKETS conditional
lpd 94-07-16 added some conditionals to help GNU `configure',
suggested by Francois Pinard <pinard@iro.umontreal.ca>;
properly erase prototype args in function parameters,
contributed by Jim Avera <jima@netcom.com>;
correct error in writeblanks (it shouldn't erase EOLs)
lpd 89-xx-xx original version
*/
/* Most of the conditionals here are to make ansi2knr work with */
/* or without the GNU configure machinery. */
#if HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <ctype.h>
#if HAVE_CONFIG_H
/*
For properly autoconfiguring ansi2knr, use AC_CONFIG_HEADER(config.h).
This will define HAVE_CONFIG_H and so, activate the following lines.
*/
# if STDC_HEADERS || HAVE_STRING_H
# include <string.h>
# else
# include <strings.h>
# endif
#else /* not HAVE_CONFIG_H */
/* Otherwise do it the hard way */
# ifdef BSD
# include <strings.h>
# else
# ifdef VMS
extern int strlen(), strncmp();
# else
# include <string.h>
# endif
# endif
#endif /* not HAVE_CONFIG_H */
#if STDC_HEADERS
# include <stdlib.h>
#else
/*
malloc and free should be declared in stdlib.h,
but if you've got a K&R compiler, they probably aren't.
*/
# ifdef MSDOS
# include <malloc.h>
# else
# ifdef VMS
extern char *malloc();
extern void free();
# else
extern char *malloc();
extern int free();
# endif
# endif
#endif
/*
* The ctype macros don't always handle 8-bit characters correctly.
* Compensate for this here.
*/
#ifdef isascii
# undef HAVE_ISASCII /* just in case */
# define HAVE_ISASCII 1
#else
#endif
#if STDC_HEADERS || !HAVE_ISASCII
# define is_ascii(c) 1
#else
# define is_ascii(c) isascii(c)
#endif
#define is_space(c) (is_ascii(c) && isspace(c))
#define is_alpha(c) (is_ascii(c) && isalpha(c))
#define is_alnum(c) (is_ascii(c) && isalnum(c))
/* Scanning macros */
#define isidchar(ch) (is_alnum(ch) || (ch) == '_')
#define isidfirstchar(ch) (is_alpha(ch) || (ch) == '_')
/* Forward references */
char *skipspace();
int writeblanks();
int test1();
int convert1();
/* The main program */
int
main(argc, argv)
int argc;
char *argv[];
{ FILE *in, *out;
#define bufsize 5000 /* arbitrary size */
char *buf;
char *line;
char *more;
/*
* In previous versions, ansi2knr recognized a --varargs switch.
* If this switch was supplied, ansi2knr would attempt to convert
* a ... argument to va_alist and va_dcl; if this switch was not
* supplied, ansi2knr would simply drop any such arguments.
* Now, ansi2knr always does this conversion, and we only
* check for this switch for backward compatibility.
*/
int convert_varargs = 1;
if ( argc > 1 && argv[1][0] == '-' )
{ if ( !strcmp(argv[1], "--varargs") )
{ convert_varargs = 1;
argc--;
argv++;
}
else
{ fprintf(stderr, "Unrecognized switch: %s\n", argv[1]);
exit(1);
}
}
switch ( argc )
{
default:
printf("Usage: ansi2knr input_file [output_file]\n");
exit(0);
case 2:
out = stdout;
break;
case 3:
out = fopen(argv[2], "w");
if ( out == NULL )
{ fprintf(stderr, "Cannot open output file %s\n", argv[2]);
exit(1);
}
}
in = fopen(argv[1], "r");
if ( in == NULL )
{ fprintf(stderr, "Cannot open input file %s\n", argv[1]);
exit(1);
}
fprintf(out, "#line 1 \"%s\"\n", argv[1]);
buf = malloc(bufsize);
line = buf;
while ( fgets(line, (unsigned)(buf + bufsize - line), in) != NULL )
{
test: line += strlen(line);
switch ( test1(buf) )
{
case 2: /* a function header */
convert1(buf, out, 1, convert_varargs);
break;
case 1: /* a function */
/* Check for a { at the start of the next line. */
more = ++line;
f: if ( line >= buf + (bufsize - 1) ) /* overflow check */
goto wl;
if ( fgets(line, (unsigned)(buf + bufsize - line), in) == NULL )
goto wl;
switch ( *skipspace(more, 1) )
{
case '{':
/* Definitely a function header. */
convert1(buf, out, 0, convert_varargs);
fputs(more, out);
break;
case 0:
/* The next line was blank or a comment: */
/* keep scanning for a non-comment. */
line += strlen(line);
goto f;
default:
/* buf isn't a function header, but */
/* more might be. */
fputs(buf, out);
strcpy(buf, more);
line = buf;
goto test;
}
break;
case -1: /* maybe the start of a function */
if ( line != buf + (bufsize - 1) ) /* overflow check */
continue;
/* falls through */
default: /* not a function */
wl: fputs(buf, out);
break;
}
line = buf;
}
if ( line != buf )
fputs(buf, out);
free(buf);
fclose(out);
fclose(in);
return 0;
}
/* Skip over space and comments, in either direction. */
char *
skipspace(p, dir)
register char *p;
register int dir; /* 1 for forward, -1 for backward */
{ for ( ; ; )
{ while ( is_space(*p) )
p += dir;
if ( !(*p == '/' && p[dir] == '*') )
break;
p += dir; p += dir;
while ( !(*p == '*' && p[dir] == '/') )
{ if ( *p == 0 )
return p; /* multi-line comment?? */
p += dir;
}
p += dir; p += dir;
}
return p;
}
/*
* Write blanks over part of a string.
* Don't overwrite end-of-line characters.
*/
int
writeblanks(start, end)
char *start;
char *end;
{ char *p;
for ( p = start; p < end; p++ )
if ( *p != '\r' && *p != '\n' )
*p = ' ';
return 0;
}
/*
* Test whether the string in buf is a function definition.
* The string may contain and/or end with a newline.
* Return as follows:
* 0 - definitely not a function definition;
* 1 - definitely a function definition;
* 2 - definitely a function prototype (NOT USED);
* -1 - may be the beginning of a function definition,
* append another line and look again.
* The reason we don't attempt to convert function prototypes is that
* Ghostscript's declaration-generating macros look too much like
* prototypes, and confuse the algorithms.
*/
int
test1(buf)
char *buf;
{ register char *p = buf;
char *bend;
char *endfn;
int contin;
if ( !isidfirstchar(*p) )
return 0; /* no name at left margin */
bend = skipspace(buf + strlen(buf) - 1, -1);
switch ( *bend )
{
case ';': contin = 0 /*2*/; break;
case ')': contin = 1; break;
case '{': return 0; /* not a function */
case '}': return 0; /* not a function */
default: contin = -1;
}
while ( isidchar(*p) )
p++;
endfn = p;
p = skipspace(p, 1);
if ( *p++ != '(' )
return 0; /* not a function */
p = skipspace(p, 1);
if ( *p == ')' )
return 0; /* no parameters */
/* Check that the apparent function name isn't a keyword. */
/* We only need to check for keywords that could be followed */
/* by a left parenthesis (which, unfortunately, is most of them). */
{ static char *words[] =
{ "asm", "auto", "case", "char", "const", "double",
"extern", "float", "for", "if", "int", "long",
"register", "return", "short", "signed", "sizeof",
"static", "switch", "typedef", "unsigned",
"void", "volatile", "while", 0
};
char **key = words;
char *kp;
int len = endfn - buf;
while ( (kp = *key) != 0 )
{ if ( strlen(kp) == len && !strncmp(kp, buf, len) )
return 0; /* name is a keyword */
key++;
}
}
return contin;
}
/* Convert a recognized function definition or header to K&R syntax. */
int
convert1(buf, out, header, convert_varargs)
char *buf;
FILE *out;
int header; /* Boolean */
int convert_varargs; /* Boolean */
{ char *endfn;
register char *p;
char **breaks;
unsigned num_breaks = 2; /* for testing */
char **btop;
char **bp;
char **ap;
char *vararg = 0;
/* Pre-ANSI implementations don't agree on whether strchr */
/* is called strchr or index, so we open-code it here. */
for ( endfn = buf; *(endfn++) != '('; )
;
top: p = endfn;
breaks = (char **)malloc(sizeof(char *) * num_breaks * 2);
if ( breaks == 0 )
{ /* Couldn't allocate break table, give up */
fprintf(stderr, "Unable to allocate break table!\n");
fputs(buf, out);
return -1;
}
btop = breaks + num_breaks * 2 - 2;
bp = breaks;
/* Parse the argument list */
do
{ int level = 0;
char *lp = NULL;
char *rp;
char *end = NULL;
if ( bp >= btop )
{ /* Filled up break table. */
/* Allocate a bigger one and start over. */
free((char *)breaks);
num_breaks <<= 1;
goto top;
}
*bp++ = p;
/* Find the end of the argument */
for ( ; end == NULL; p++ )
{ switch(*p)
{
case ',':
if ( !level ) end = p;
break;
case '(':
if ( !level ) lp = p;
level++;
break;
case ')':
if ( --level < 0 ) end = p;
else rp = p;
break;
case '/':
p = skipspace(p, 1) - 1;
break;
default:
;
}
}
/* Erase any embedded prototype parameters. */
if ( lp )
writeblanks(lp + 1, rp);
p--; /* back up over terminator */
/* Find the name being declared. */
/* This is complicated because of procedure and */
/* array modifiers. */
for ( ; ; )
{ p = skipspace(p - 1, -1);
switch ( *p )
{
case ']': /* skip array dimension(s) */
case ')': /* skip procedure args OR name */
{ int level = 1;
while ( level )
switch ( *--p )
{
case ']': case ')': level++; break;
case '[': case '(': level--; break;
case '/': p = skipspace(p, -1) + 1; break;
default: ;
}
}
if ( *p == '(' && *skipspace(p + 1, 1) == '*' )
{ /* We found the name being declared */
while ( !isidfirstchar(*p) )
p = skipspace(p, 1) + 1;
goto found;
}
break;
default:
goto found;
}
}
found: if ( *p == '.' && p[-1] == '.' && p[-2] == '.' )
{ if ( convert_varargs )
{ *bp++ = "va_alist";
vararg = p-2;
}
else
{ p++;
if ( bp == breaks + 1 ) /* sole argument */
writeblanks(breaks[0], p);
else
writeblanks(bp[-1] - 1, p);
bp--;
}
}
else
{ while ( isidchar(*p) ) p--;
*bp++ = p+1;
}
p = end;
}
while ( *p++ == ',' );
*bp = p;
/* Make a special check for 'void' arglist */
if ( bp == breaks+2 )
{ p = skipspace(breaks[0], 1);
if ( !strncmp(p, "void", 4) )
{ p = skipspace(p+4, 1);
if ( p == breaks[2] - 1 )
{ bp = breaks; /* yup, pretend arglist is empty */
writeblanks(breaks[0], p + 1);
}
}
}
/* Put out the function name and left parenthesis. */
p = buf;
while ( p != endfn ) putc(*p, out), p++;
/* Put out the declaration. */
if ( header )
{ fputs(");", out);
for ( p = breaks[0]; *p; p++ )
if ( *p == '\r' || *p == '\n' )
putc(*p, out);
}
else
{ for ( ap = breaks+1; ap < bp; ap += 2 )
{ p = *ap;
while ( isidchar(*p) )
putc(*p, out), p++;
if ( ap < bp - 1 )
fputs(", ", out);
}
fputs(") ", out);
/* Put out the argument declarations */
for ( ap = breaks+2; ap <= bp; ap += 2 )
(*ap)[-1] = ';';
if ( vararg != 0 )
{ *vararg = 0;
fputs(breaks[0], out); /* any prior args */
fputs("va_dcl", out); /* the final arg */
fputs(bp[0], out);
}
else
fputs(breaks[0], out);
}
free((char *)breaks);
return 0;
}

370
bmp.c Normal file
View File

@@ -0,0 +1,370 @@
/* Copyright (C)2004 Landmark Graphics Corporation
* Copyright (C)2005 Sun Microsystems, Inc.
*
* This library is free software and may be redistributed and/or modified under
* the terms of the wxWindows Library License, Version 3.1 or (at your option)
* any later version. The full license is in the LICENSE.txt file included
* with this distribution.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* wxWindows Library License for more details.
*/
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef _WIN32
#include <io.h>
#else
#include <unistd.h>
#endif
#include "./rrutil.h"
#include "./bmp.h"
#ifndef BI_BITFIELDS
#define BI_BITFIELDS 3L
#endif
#ifndef BI_RGB
#define BI_RGB 0L
#endif
#define BMPHDRSIZE 54
typedef struct _bmphdr
{
unsigned short bfType;
unsigned int bfSize;
unsigned short bfReserved1, bfReserved2;
unsigned int bfOffBits;
unsigned int biSize;
int biWidth, biHeight;
unsigned short biPlanes, biBitCount;
unsigned int biCompression, biSizeImage;
int biXPelsPerMeter, biYPelsPerMeter;
unsigned int biClrUsed, biClrImportant;
} bmphdr;
static const char *__bmperr="No error";
static const int ps[BMPPIXELFORMATS]={3, 4, 3, 4, 4, 4};
static const int roffset[BMPPIXELFORMATS]={0, 0, 2, 2, 3, 1};
static const int goffset[BMPPIXELFORMATS]={1, 1, 1, 1, 2, 2};
static const int boffset[BMPPIXELFORMATS]={2, 2, 0, 0, 1, 3};
#define _throw(m) {__bmperr=m; retcode=-1; goto finally;}
#define _unix(f) {if((f)==-1) _throw(strerror(errno));}
#define _catch(f) {if((f)==-1) {retcode=-1; goto finally;}}
#define readme(fd, addr, size) \
if((bytesread=read(fd, addr, (size)))==-1) _throw(strerror(errno)); \
if(bytesread!=(size)) _throw("Read error");
void pixelconvert(unsigned char *srcbuf, enum BMPPIXELFORMAT srcformat,
int srcpitch, unsigned char *dstbuf, enum BMPPIXELFORMAT dstformat, int dstpitch,
int w, int h, int flip)
{
unsigned char *srcptr, *srcptr0, *dstptr, *dstptr0;
int i, j;
srcptr=flip? &srcbuf[srcpitch*(h-1)]:srcbuf;
for(j=0, dstptr=dstbuf; j<h; j++,
srcptr+=flip? -srcpitch:srcpitch, dstptr+=dstpitch)
{
for(i=0, srcptr0=srcptr, dstptr0=dstptr; i<w; i++,
srcptr0+=ps[srcformat], dstptr0+=ps[dstformat])
{
dstptr0[roffset[dstformat]]=srcptr0[roffset[srcformat]];
dstptr0[goffset[dstformat]]=srcptr0[goffset[srcformat]];
dstptr0[boffset[dstformat]]=srcptr0[boffset[srcformat]];
}
}
}
int loadppm(int *fd, unsigned char **buf, int *w, int *h,
enum BMPPIXELFORMAT f, int align, int dstbottomup, int ascii)
{
FILE *fs=NULL; int retcode=0, scalefactor, dstpitch;
unsigned char *tempbuf=NULL; char temps[255], temps2[255];
int numread=0, totalread=0, pixel[3], i, j;
if((fs=fdopen(*fd, "r"))==NULL) _throw(strerror(errno));
do
{
if(!fgets(temps, 255, fs)) _throw("Read error");
if(strlen(temps)==0 || temps[0]=='\n') continue;
if(sscanf(temps, "%s", temps2)==1 && temps2[1]=='#') continue;
switch(totalread)
{
case 0:
if((numread=sscanf(temps, "%d %d %d", w, h, &scalefactor))==EOF)
_throw("Read error");
break;
case 1:
if((numread=sscanf(temps, "%d %d", h, &scalefactor))==EOF)
_throw("Read error");
break;
case 2:
if((numread=sscanf(temps, "%d", &scalefactor))==EOF)
_throw("Read error");
break;
}
totalread+=numread;
} while(totalread<3);
if((*w)<1 || (*h)<1 || scalefactor<1) _throw("Corrupt PPM header");
dstpitch=(((*w)*ps[f])+(align-1))&(~(align-1));
if((*buf=(unsigned char *)malloc(dstpitch*(*h)))==NULL)
_throw("Memory allocation error");
if(ascii)
{
for(j=0; j<*h; j++)
{
for(i=0; i<*w; i++)
{
if(fscanf(fs, "%d%d%d", &pixel[0], &pixel[1], &pixel[2])!=3)
_throw("Read error");
(*buf)[j*dstpitch+i*ps[f]+roffset[f]]=(unsigned char)(pixel[0]*255/scalefactor);
(*buf)[j*dstpitch+i*ps[f]+goffset[f]]=(unsigned char)(pixel[1]*255/scalefactor);
(*buf)[j*dstpitch+i*ps[f]+boffset[f]]=(unsigned char)(pixel[2]*255/scalefactor);
}
}
}
else
{
if(scalefactor!=255)
_throw("Binary PPMs must have 8-bit components");
if((tempbuf=(unsigned char *)malloc((*w)*(*h)*3))==NULL)
_throw("Memory allocation error");
if(fread(tempbuf, (*w)*(*h)*3, 1, fs)!=1) _throw("Read error");
pixelconvert(tempbuf, BMP_RGB, (*w)*3, *buf, f, dstpitch, *w, *h, dstbottomup);
}
finally:
if(fs) {fclose(fs); *fd=-1;}
if(tempbuf) free(tempbuf);
return retcode;
}
int loadbmp(char *filename, unsigned char **buf, int *w, int *h,
enum BMPPIXELFORMAT f, int align, int dstbottomup)
{
int fd=-1, bytesread, srcpitch, srcbottomup=1, srcps, dstpitch,
retcode=0;
unsigned char *tempbuf=NULL;
bmphdr bh; int flags=O_RDONLY;
dstbottomup=dstbottomup? 1:0;
#ifdef _WIN32
flags|=O_BINARY;
#endif
if(!filename || !buf || !w || !h || f<0 || f>BMPPIXELFORMATS-1 || align<1)
_throw("invalid argument to loadbmp()");
if((align&(align-1))!=0)
_throw("Alignment must be a power of 2");
_unix(fd=open(filename, flags));
readme(fd, &bh.bfType, sizeof(unsigned short));
if(!littleendian()) bh.bfType=byteswap16(bh.bfType);
if(bh.bfType==0x3650)
{
_catch(loadppm(&fd, buf, w, h, f, align, dstbottomup, 0));
goto finally;
}
if(bh.bfType==0x3350)
{
_catch(loadppm(&fd, buf, w, h, f, align, dstbottomup, 1));
goto finally;
}
readme(fd, &bh.bfSize, sizeof(unsigned int));
readme(fd, &bh.bfReserved1, sizeof(unsigned short));
readme(fd, &bh.bfReserved2, sizeof(unsigned short));
readme(fd, &bh.bfOffBits, sizeof(unsigned int));
readme(fd, &bh.biSize, sizeof(unsigned int));
readme(fd, &bh.biWidth, sizeof(int));
readme(fd, &bh.biHeight, sizeof(int));
readme(fd, &bh.biPlanes, sizeof(unsigned short));
readme(fd, &bh.biBitCount, sizeof(unsigned short));
readme(fd, &bh.biCompression, sizeof(unsigned int));
readme(fd, &bh.biSizeImage, sizeof(unsigned int));
readme(fd, &bh.biXPelsPerMeter, sizeof(int));
readme(fd, &bh.biYPelsPerMeter, sizeof(int));
readme(fd, &bh.biClrUsed, sizeof(unsigned int));
readme(fd, &bh.biClrImportant, sizeof(unsigned int));
if(!littleendian())
{
bh.bfSize=byteswap(bh.bfSize);
bh.bfOffBits=byteswap(bh.bfOffBits);
bh.biSize=byteswap(bh.biSize);
bh.biWidth=byteswap(bh.biWidth);
bh.biHeight=byteswap(bh.biHeight);
bh.biPlanes=byteswap16(bh.biPlanes);
bh.biBitCount=byteswap16(bh.biBitCount);
bh.biCompression=byteswap(bh.biCompression);
bh.biSizeImage=byteswap(bh.biSizeImage);
bh.biXPelsPerMeter=byteswap(bh.biXPelsPerMeter);
bh.biYPelsPerMeter=byteswap(bh.biYPelsPerMeter);
bh.biClrUsed=byteswap(bh.biClrUsed);
bh.biClrImportant=byteswap(bh.biClrImportant);
}
if(bh.bfType!=0x4d42 || bh.bfOffBits<BMPHDRSIZE
|| bh.biWidth<1 || bh.biHeight==0)
_throw("Corrupt bitmap header");
if((bh.biBitCount!=24 && bh.biBitCount!=32) || bh.biCompression!=BI_RGB)
_throw("Only uncompessed RGB bitmaps are supported");
*w=bh.biWidth; *h=bh.biHeight; srcps=bh.biBitCount/8;
if(*h<0) {*h=-(*h); srcbottomup=0;}
srcpitch=(((*w)*srcps)+3)&(~3);
dstpitch=(((*w)*ps[f])+(align-1))&(~(align-1));
if(srcpitch*(*h)+bh.bfOffBits!=bh.bfSize) _throw("Corrupt bitmap header");
if((tempbuf=(unsigned char *)malloc(srcpitch*(*h)))==NULL
|| (*buf=(unsigned char *)malloc(dstpitch*(*h)))==NULL)
_throw("Memory allocation error");
if(lseek(fd, (long)bh.bfOffBits, SEEK_SET)!=(long)bh.bfOffBits)
_throw(strerror(errno));
_unix(bytesread=read(fd, tempbuf, srcpitch*(*h)));
if(bytesread!=srcpitch*(*h)) _throw("Read error");
pixelconvert(tempbuf, BMP_BGR, srcpitch, *buf, f, dstpitch, *w, *h,
srcbottomup!=dstbottomup);
finally:
if(tempbuf) free(tempbuf);
if(fd!=-1) close(fd);
return retcode;
}
#define writeme(fd, addr, size) \
if((byteswritten=write(fd, addr, (size)))==-1) _throw(strerror(errno)); \
if(byteswritten!=(size)) _throw("Write error");
int saveppm(char *filename, unsigned char *buf, int w, int h,
enum BMPPIXELFORMAT f, int srcpitch, int srcbottomup)
{
FILE *fs=NULL; int retcode=0;
unsigned char *tempbuf=NULL;
if((fs=fopen(filename, "wb"))==NULL) _throw(strerror(errno));
if(fprintf(fs, "P6\n")<1) _throw("Write error");
if(fprintf(fs, "%d %d\n", w, h)<1) _throw("Write error");
if(fprintf(fs, "255\n")<1) _throw("Write error");
if((tempbuf=(unsigned char *)malloc(w*h*3))==NULL)
_throw("Memory allocation error");
pixelconvert(buf, f, srcpitch, tempbuf, BMP_RGB, w*3, w, h,
srcbottomup);
if((fwrite(tempbuf, w*h*3, 1, fs))!=1) _throw("Write error");
finally:
if(tempbuf) free(tempbuf);
if(fs) fclose(fs);
return retcode;
}
int savebmp(char *filename, unsigned char *buf, int w, int h,
enum BMPPIXELFORMAT f, int srcpitch, int srcbottomup)
{
int fd=-1, byteswritten, dstpitch, retcode=0;
int flags=O_RDWR|O_CREAT|O_TRUNC;
unsigned char *tempbuf=NULL; char *temp;
bmphdr bh; int mode;
#ifdef _WIN32
flags|=O_BINARY; mode=_S_IREAD|_S_IWRITE;
#else
mode=S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH;
#endif
if(!filename || !buf || w<1 || h<1 || f<0 || f>BMPPIXELFORMATS-1 || srcpitch<0)
_throw("bad argument to savebmp()");
if(srcpitch==0) srcpitch=w*ps[f];
if((temp=strrchr(filename, '.'))!=NULL)
{
if(!stricmp(temp, ".ppm"))
return saveppm(filename, buf, w, h, f, srcpitch, srcbottomup);
}
_unix(fd=open(filename, flags, mode));
dstpitch=((w*3)+3)&(~3);
bh.bfType=0x4d42;
bh.bfSize=BMPHDRSIZE+dstpitch*h;
bh.bfReserved1=0; bh.bfReserved2=0;
bh.bfOffBits=BMPHDRSIZE;
bh.biSize=40;
bh.biWidth=w; bh.biHeight=h;
bh.biPlanes=0; bh.biBitCount=24;
bh.biCompression=BI_RGB; bh.biSizeImage=0;
bh.biXPelsPerMeter=0; bh.biYPelsPerMeter=0;
bh.biClrUsed=0; bh.biClrImportant=0;
if(!littleendian())
{
bh.bfType=byteswap16(bh.bfType);
bh.bfSize=byteswap(bh.bfSize);
bh.bfOffBits=byteswap(bh.bfOffBits);
bh.biSize=byteswap(bh.biSize);
bh.biWidth=byteswap(bh.biWidth);
bh.biHeight=byteswap(bh.biHeight);
bh.biPlanes=byteswap16(bh.biPlanes);
bh.biBitCount=byteswap16(bh.biBitCount);
bh.biCompression=byteswap(bh.biCompression);
bh.biSizeImage=byteswap(bh.biSizeImage);
bh.biXPelsPerMeter=byteswap(bh.biXPelsPerMeter);
bh.biYPelsPerMeter=byteswap(bh.biYPelsPerMeter);
bh.biClrUsed=byteswap(bh.biClrUsed);
bh.biClrImportant=byteswap(bh.biClrImportant);
}
writeme(fd, &bh.bfType, sizeof(unsigned short));
writeme(fd, &bh.bfSize, sizeof(unsigned int));
writeme(fd, &bh.bfReserved1, sizeof(unsigned short));
writeme(fd, &bh.bfReserved2, sizeof(unsigned short));
writeme(fd, &bh.bfOffBits, sizeof(unsigned int));
writeme(fd, &bh.biSize, sizeof(unsigned int));
writeme(fd, &bh.biWidth, sizeof(int));
writeme(fd, &bh.biHeight, sizeof(int));
writeme(fd, &bh.biPlanes, sizeof(unsigned short));
writeme(fd, &bh.biBitCount, sizeof(unsigned short));
writeme(fd, &bh.biCompression, sizeof(unsigned int));
writeme(fd, &bh.biSizeImage, sizeof(unsigned int));
writeme(fd, &bh.biXPelsPerMeter, sizeof(int));
writeme(fd, &bh.biYPelsPerMeter, sizeof(int));
writeme(fd, &bh.biClrUsed, sizeof(unsigned int));
writeme(fd, &bh.biClrImportant, sizeof(unsigned int));
if((tempbuf=(unsigned char *)malloc(dstpitch*h))==NULL)
_throw("Memory allocation error");
pixelconvert(buf, f, srcpitch, tempbuf, BMP_BGR, dstpitch, w, h,
!srcbottomup);
if((byteswritten=write(fd, tempbuf, dstpitch*h))!=dstpitch*h)
_throw(strerror(errno));
finally:
if(tempbuf) free(tempbuf);
if(fd!=-1) close(fd);
return retcode;
}
const char *bmpgeterr(void)
{
return __bmperr;
}

48
bmp.h Normal file
View File

@@ -0,0 +1,48 @@
/* Copyright (C)2004 Landmark Graphics Corporation
* Copyright (C)2005 Sun Microsystems, Inc.
*
* This library is free software and may be redistributed and/or modified under
* the terms of the wxWindows Library License, Version 3.1 or (at your option)
* any later version. The full license is in the LICENSE.txt file included
* with this distribution.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* wxWindows Library License for more details.
*/
// This provides rudimentary facilities for loading and saving true color
// BMP and PPM files
#ifndef __BMP_H__
#define __BMP_H__
#define BMPPIXELFORMATS 6
enum BMPPIXELFORMAT {BMP_RGB=0, BMP_RGBA, BMP_BGR, BMP_BGRA, BMP_ABGR, BMP_ARGB};
#ifdef __cplusplus
extern "C" {
#endif
// This will load a Windows bitmap from a file and return a buffer with the
// specified pixel format, scanline alignment, and orientation. The width and
// height are returned in w and h.
int loadbmp(char *filename, unsigned char **buf, int *w, int *h,
enum BMPPIXELFORMAT f, int align, int dstbottomup);
// This will save a buffer with the specified pixel format, pitch, orientation,
// width, and height as a 24-bit Windows bitmap or PPM (the filename determines
// which format to use)
int savebmp(char *filename, unsigned char *buf, int w, int h,
enum BMPPIXELFORMAT f, int srcpitch, int srcbottomup);
const char *bmpgeterr(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,7 +1,8 @@
/*
* cderror.h
*
* Copyright (C) 1994, Thomas G. Lane.
* Copyright (C) 1994-1997, Thomas G. Lane.
* Modified 2009 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -45,6 +46,7 @@ JMESSAGE(JERR_BMP_BADHEADER, "Invalid BMP file: bad header length")
JMESSAGE(JERR_BMP_BADPLANES, "Invalid BMP file: biPlanes not equal to 1")
JMESSAGE(JERR_BMP_COLORSPACE, "BMP output must be grayscale or RGB")
JMESSAGE(JERR_BMP_COMPRESSED, "Sorry, compressed BMPs not yet supported")
JMESSAGE(JERR_BMP_EMPTY, "Empty BMP image")
JMESSAGE(JERR_BMP_NOT, "Not a BMP file - does not start with BM")
JMESSAGE(JTRC_BMP, "%ux%u 24-bit BMP image")
JMESSAGE(JTRC_BMP_MAPPED, "%ux%u 8-bit colormapped BMP image")
@@ -72,7 +74,7 @@ JMESSAGE(JWRN_GIF_NOMOREDATA, "Ran out of GIF bits")
#ifdef PPM_SUPPORTED
JMESSAGE(JERR_PPM_COLORSPACE, "PPM output must be grayscale or RGB")
JMESSAGE(JERR_PPM_NONNUMERIC, "Nonnumeric data in PPM file")
JMESSAGE(JERR_PPM_NOT, "Not a PPM file")
JMESSAGE(JERR_PPM_NOT, "Not a PPM/PGM file")
JMESSAGE(JTRC_PGM, "%ux%u PGM image")
JMESSAGE(JTRC_PGM_TEXT, "%ux%u text PGM image")
JMESSAGE(JTRC_PPM, "%ux%u PPM image")

View File

@@ -1,7 +1,7 @@
/*
* cdjpeg.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Copyright (C) 1991-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -47,7 +47,9 @@ GLOBAL(void)
enable_signal_catcher (j_common_ptr cinfo)
{
sig_cinfo = cinfo;
#ifdef SIGINT /* not all systems have SIGINT */
signal(SIGINT, signal_catcher);
#endif
#ifdef SIGTERM /* not all systems have SIGTERM */
signal(SIGTERM, signal_catcher);
#endif

View File

@@ -1,7 +1,7 @@
/*
* cdjpeg.h
*
* Copyright (C) 1994-1996, Thomas G. Lane.
* Copyright (C) 1994-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -104,6 +104,7 @@ typedef struct cdjpeg_progress_mgr * cd_progress_ptr;
#define jinit_write_targa jIWrTarga
#define read_quant_tables RdQTables
#define read_scan_script RdScnScript
#define set_quality_ratings SetQRates
#define set_quant_slots SetQSlots
#define set_sample_factors SetSFacts
#define read_color_map RdCMap
@@ -131,8 +132,10 @@ EXTERN(djpeg_dest_ptr) jinit_write_targa JPP((j_decompress_ptr cinfo));
/* cjpeg support routines (in rdswitch.c) */
EXTERN(boolean) read_quant_tables JPP((j_compress_ptr cinfo, char * filename,
int scale_factor, boolean force_baseline));
boolean force_baseline));
EXTERN(boolean) read_scan_script JPP((j_compress_ptr cinfo, char * filename));
EXTERN(boolean) set_quality_ratings JPP((j_compress_ptr cinfo, char *arg,
boolean force_baseline));
EXTERN(boolean) set_quant_slots JPP((j_compress_ptr cinfo, char *arg));
EXTERN(boolean) set_sample_factors JPP((j_compress_ptr cinfo, char *arg));
@@ -156,9 +159,14 @@ EXTERN(FILE *) write_stdout JPP((void));
#define READ_BINARY "r"
#define WRITE_BINARY "w"
#else
#ifdef VMS /* VMS is very nonstandard */
#define READ_BINARY "rb", "ctx=stm"
#define WRITE_BINARY "wb", "ctx=stm"
#else /* standard ANSI-compliant case */
#define READ_BINARY "rb"
#define WRITE_BINARY "wb"
#endif
#endif
#ifndef EXIT_FAILURE /* define exit() codes if not provided */
#define EXIT_FAILURE 1

View File

@@ -1,6 +1,132 @@
CHANGE LOG for Independent JPEG Group's JPEG software
Version 8b 16-May-2010
-----------------------
Repair problem in new memory source manager with corrupt JPEG data.
Thank to Ted Campbell and Samuel Chun for the report.
Version 8a 28-Feb-2010
-----------------------
Writing tables-only datastreams via jpeg_write_tables works again.
Support 32-bit BMPs (RGB image with Alpha channel) for read in cjpeg.
Thank to Brett Blackham for the suggestion.
Version 8 10-Jan-2010
----------------------
Add sanity check in BMP reader module to avoid cjpeg crash for empty input
image (thank to Isaev Ildar of ISP RAS, Moscow, RU for reporting this error).
Add data source and destination managers for read from and write to
memory buffers. New API functions jpeg_mem_src and jpeg_mem_dest.
Thank to Roberto Boni from Italy for the suggestion.
Version 7 27-Jun-2009
----------------------
cjpeg -quality option has been extended for support of separate quality
settings for luminance and chrominance (or in general, for every provided
quantization table slot).
New API function jpeg_default_qtables() and q_scale_factor array in library.
Support arithmetic entropy encoding and decoding.
Added files jaricom.c, jcarith.c, jdarith.c.
jpegtran has a new "lossless" cropping feature.
Implement -perfect option in jpegtran, new API function
jtransform_perfect_transform() in transupp. (DP 204_perfect.dpatch)
Better error messages for jpegtran fopen failure.
(DP 203_jpegtran_errmsg.dpatch)
Fix byte order issue with 16bit PPM/PGM files in rdppm.c/wrppm.c:
according to Netpbm, the de facto standard implementation of the PNM formats,
the most significant byte is first. (DP 203_rdppm.dpatch)
Add -raw option to rdjpgcom not to mangle the output.
(DP 205_rdjpgcom_raw.dpatch)
Make rdjpgcom locale aware. (DP 201_rdjpgcom_locale.dpatch)
Add extern "C" to jpeglib.h.
This avoids the need to put extern "C" { ... } around #include "jpeglib.h"
in your C++ application. Defining the symbol DONT_USE_EXTERN_C in the
configuration prevents this. (DP 202_jpeglib.h_c++.dpatch)
Version 6b 27-Mar-1998
-----------------------
jpegtran has new features for lossless image transformations (rotation
and flipping) as well as "lossless" reduction to grayscale.
jpegtran now copies comments by default; it has a -copy switch to enable
copying all APPn blocks as well, or to suppress comments. (Formerly it
always suppressed comments and APPn blocks.) jpegtran now also preserves
JFIF version and resolution information.
New decompressor library feature: COM and APPn markers found in the input
file can be saved in memory for later use by the application. (Before,
you had to code this up yourself with a custom marker processor.)
There is an unused field "void * client_data" now in compress and decompress
parameter structs; this may be useful in some applications.
JFIF version number information is now saved by the decoder and accepted by
the encoder. jpegtran uses this to copy the source file's version number,
to ensure "jpegtran -copy all" won't create bogus files that contain JFXX
extensions but claim to be version 1.01. Applications that generate their
own JFXX extension markers also (finally) have a supported way to cause the
encoder to emit JFIF version number 1.02.
djpeg's trace mode reports JFIF 1.02 thumbnail images as such, rather
than as unknown APP0 markers.
In -verbose mode, djpeg and rdjpgcom will try to print the contents of
APP12 markers as text. Some digital cameras store useful text information
in APP12 markers.
Handling of truncated data streams is more robust: blocks beyond the one in
which the error occurs will be output as uniform gray, or left unchanged
if decoding a progressive JPEG. The appearance no longer depends on the
Huffman tables being used.
Huffman tables are checked for validity much more carefully than before.
To avoid the Unisys LZW patent, djpeg's GIF output capability has been
changed to produce "uncompressed GIFs", and cjpeg's GIF input capability
has been removed altogether. We're not happy about it either, but there
seems to be no good alternative.
The configure script now supports building libjpeg as a shared library
on many flavors of Unix (all the ones that GNU libtool knows how to
build shared libraries for). Use "./configure --enable-shared" to
try this out.
New jconfig file and makefiles for Microsoft Visual C++ and Developer Studio.
Also, a jconfig file and a build script for Metrowerks CodeWarrior
on Apple Macintosh. makefile.dj has been updated for DJGPP v2, and there
are miscellaneous other minor improvements in the makefiles.
jmemmac.c now knows how to create temporary files following Mac System 7
conventions.
djpeg's -map switch is now able to read raw-format PPM files reliably.
cjpeg -progressive -restart no longer generates any unnecessary DRI markers.
Multiple calls to jpeg_simple_progression for a single JPEG object
no longer leak memory.
Version 6a 7-Feb-96
--------------------

80
cjpeg.1
View File

@@ -1,4 +1,4 @@
.TH CJPEG 1 "15 June 1995"
.TH CJPEG 1 "11 October 2010"
.SH NAME
cjpeg \- compress an image file to a JPEG file
.SH SYNOPSIS
@@ -16,7 +16,7 @@ cjpeg \- compress an image file to a JPEG file
compresses the named image file, or the standard input if no file is
named, and produces a JPEG/JFIF file on the standard output.
The currently supported input file formats are: PPM (PBMPLUS color
format), PGM (PBMPLUS gray-scale format), BMP, GIF, Targa, and RLE (Utah Raster
format), PGM (PBMPLUS gray-scale format), BMP, Targa, and RLE (Utah Raster
Toolkit format). (RLE is supported only if the URT library is available.)
.SH OPTIONS
All switch names may be abbreviated; for example,
@@ -27,24 +27,24 @@ or
.BR \-gr .
Most of the "basic" switches can be abbreviated to as little as one letter.
Upper and lower case are equivalent (thus
.B \-GIF
.B \-BMP
is the same as
.BR \-gif ).
.BR \-bmp ).
British spellings are also accepted (e.g.,
.BR \-greyscale ),
though for brevity these are not mentioned below.
.PP
The basic switches are:
.TP
.BI \-quality " N"
.BI \-quality " N[,...]"
Scale quantization tables to adjust image quality. Quality is 0 (worst) to
100 (best); default is 75. (See below for more info.)
.TP
.B \-grayscale
Create monochrome JPEG file from color input. Be sure to use this switch when
compressing a grayscale GIF file, because
compressing a grayscale BMP file, because
.B cjpeg
isn't bright enough to notice whether a GIF file uses only shades of gray.
isn't bright enough to notice whether a BMP file uses only shades of gray.
By saying
.BR \-grayscale ,
you'll get a smaller JPEG file that takes less time to process.
@@ -108,6 +108,36 @@ other JPEG programs may be unable to decode the resulting file. Use
.B \-baseline
if you need to ensure compatibility at low quality values.)
.PP
The \fB-quality\fR option has been extended in this version of \fBcjpeg\fR to
support separate quality settings for luminance and chrominance (or, in
general, separate settings for every quantization table slot.) The principle
is the same as chrominance subsampling: since the human eye is more sensitive
to spatial changes in brightness than spatial changes in color, the chrominance
components can be quantized more than the luminance components without
incurring any visible image quality loss. However, unlike subsampling, this
feature reduces data in the frequency domain instead of the spatial domain,
which allows for more fine-grained control. This option is useful in
quality-sensitive applications, for which the artifacts generated by
subsampling may be unacceptable.
.PP
The \fB-quality\fR option accepts a comma-separated list of parameters, which
respectively refer to the quality levels which should be assigned to the
quantization table slots. If there are more q-table slots than parameters,
then the last parameter is replicated. Thus, if only one quality parameter is
given, this is used for both luminance and chrominance (slots 0 and 1,
respectively), preserving the legacy behavior of cjpeg v6b and prior.
More (or customized) quantization tables can be set with the \fB-qtables\fR
option and assigned to components with the \fB-qslots\fR option (see the
"wizard" switches below.)
.PP
JPEG files generated with separate luminance and chrominance quality are fully
compliant with standard JPEG decoders.
.PP
.BR CAUTION:
For this setting to be useful, be sure to pass an argument of \fB-sample 1x1\fR
to \fBcjpeg\fR to disable chrominance subsampling. Otherwise, the default
subsampling level (2x2, AKA "4:2:0") will be used.
.PP
The
.B \-progressive
switch creates a "progressive JPEG" file. In this type of JPEG file, the data
@@ -117,9 +147,6 @@ scan to display a low-quality image very quickly, and can then improve the
display with each subsequent scan. The final image is exactly equivalent to a
standard JPEG file of the same quality setting, and the total file size is
about the same --- often a little smaller.
.B Caution:
progressive JPEG is not yet widely implemented, so many decoders will be
unable to view a progressive JPEG file at all.
.PP
Switches for advanced users:
.TP
@@ -180,16 +207,28 @@ for images that will be transmitted across unreliable networks such as Usenet.
The
.B \-smooth
option filters the input to eliminate fine-scale noise. This is often useful
when converting GIF files to JPEG: a moderate smoothing factor of 10 to 50
gets rid of dithering patterns in the input file, resulting in a smaller JPEG
file and a better-looking image. Too large a smoothing factor will visibly
blur the image, however.
when converting dithered images to JPEG: a moderate smoothing factor of 10 to
50 gets rid of dithering patterns in the input file, resulting in a smaller
JPEG file and a better-looking image. Too large a smoothing factor will
visibly blur the image, however.
.PP
Switches for wizards:
.TP
.B \-arithmetic
Use arithmetic coding.
.B Caution:
arithmetic coded JPEG is not yet widely implemented, so many decoders will be
unable to view an arithmetic coded JPEG file at all.
.TP
.B \-baseline
Force a baseline JPEG file to be generated. This clamps quantization values
to 8 bits even at low quality settings.
Force baseline-compatible quantization tables to be generated. This clamps
quantization values to 8 bits even at low quality settings. (This switch is
poorly named, since it does not ensure that the output is actually baseline
JPEG. For example, you can use
.B \-baseline
and
.B \-progressive
together.)
.TP
.BI \-qtables " file"
Use the quantization tables given in the specified text file.
@@ -205,7 +244,7 @@ Use the scan script given in the specified text file.
.PP
The "wizard" switches are intended for experimentation with JPEG. If you
don't know what you are doing, \fBdon't use them\fR. These switches are
documented further in the file wizard.doc.
documented further in the file wizard.txt.
.SH EXAMPLES
.LP
This example compresses the PPM file foo.ppm with a quality factor of
@@ -270,7 +309,10 @@ Communications of the ACM, April 1991 (vol. 34, no. 4), pp. 30-44.
.SH AUTHOR
Independent JPEG Group
.SH BUGS
Arithmetic coding is not supported for legal reasons.
Support for GIF input files was removed in cjpeg v6b due to concerns over
the Unisys LZW patent. Although this patent expired in 2006, cjpeg still
lacks GIF support, for these historical reasons. (Conversion of GIF files to
JPEG is usually a bad idea anyway.)
.PP
Not all variants of BMP and Targa file formats are supported.
.PP
@@ -278,5 +320,3 @@ The
.B \-targa
switch is not a bug, it's a feature. (It would be a bug if the Targa format
designers had not been clueless.)
.PP
Still not as fast as we'd like.

41
cjpeg.c
View File

@@ -1,7 +1,9 @@
/*
* cjpeg.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Copyright (C) 1991-1998, Thomas G. Lane.
* Modified 2003-2008 by Guido Vollbeding.
* Copyright (C) 2010, 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.
*
@@ -25,6 +27,7 @@
#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
#include "jversion.h" /* for version message */
#include "config.h"
#ifdef USE_CCOMMAND /* command-line reader for Macintosh */
#ifdef __MWERKS__
@@ -149,7 +152,7 @@ usage (void)
#endif
fprintf(stderr, "Switches (names may be abbreviated):\n");
fprintf(stderr, " -quality N Compression quality (0..100; 5-95 is useful range)\n");
fprintf(stderr, " -quality N[,...] Compression quality (0..100; 5-95 is useful range)\n");
fprintf(stderr, " -grayscale Create monochrome JPEG file\n");
#ifdef ENTROPY_OPT_SUPPORTED
fprintf(stderr, " -optimize Optimize Huffman table (smaller file, but slow compression)\n");
@@ -184,7 +187,7 @@ usage (void)
#ifdef C_ARITH_CODING_SUPPORTED
fprintf(stderr, " -arithmetic Use arithmetic coding\n");
#endif
fprintf(stderr, " -baseline Force baseline output\n");
fprintf(stderr, " -baseline Force baseline quantization tables\n");
fprintf(stderr, " -qtables file Use quantization tables given in file\n");
fprintf(stderr, " -qslots N[,...] Set component quantization tables\n");
fprintf(stderr, " -sample HxV[,...] Set component sampling factors\n");
@@ -209,21 +212,16 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
{
int argn;
char * arg;
int quality; /* -quality parameter */
int q_scale_factor; /* scaling percentage for -qtables */
boolean force_baseline;
boolean simple_progressive;
char * qualityarg = NULL; /* saves -quality parm if any */
char * qtablefile = NULL; /* saves -qtables filename if any */
char * qslotsarg = NULL; /* saves -qslots parm if any */
char * samplearg = NULL; /* saves -sample parm if any */
char * scansarg = NULL; /* saves -scans parm if any */
/* Set up default JPEG parameters. */
/* Note that default -quality level need not, and does not,
* match the default scaling for an explicit -qtables argument.
*/
quality = 75; /* default -quality value */
q_scale_factor = 100; /* default to no scaling for -qtables */
force_baseline = FALSE; /* by default, allow 16-bit quantizers */
simple_progressive = FALSE;
is_targa = FALSE;
@@ -255,7 +253,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
#endif
} else if (keymatch(arg, "baseline", 1)) {
/* Force baseline output (8-bit quantizer values). */
/* Force baseline-compatible output (8-bit quantizer values). */
force_baseline = TRUE;
} else if (keymatch(arg, "dct", 2)) {
@@ -277,7 +275,10 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
static boolean printed_version = FALSE;
if (! printed_version) {
fprintf(stderr, "Independent JPEG Group's CJPEG, version %s\n%s\n",
fprintf(stderr, "%s version %s (build %s)\n",
PACKAGE_NAME, VERSION, BUILD);
fprintf(stderr, "%s\n\n", LJTCOPYRIGHT);
fprintf(stderr, "Based on Independent JPEG Group's libjpeg, version %s\n%s\n\n",
JVERSION, JCOPYRIGHT);
printed_version = TRUE;
}
@@ -328,13 +329,10 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
#endif
} else if (keymatch(arg, "quality", 1)) {
/* Quality factor (quantization table scaling factor). */
/* Quality ratings (quantization table scaling factors). */
if (++argn >= argc) /* advance to next argument */
usage();
if (sscanf(argv[argn], "%d", &quality) != 1)
usage();
/* Change scale factor in case -qtables is present. */
q_scale_factor = jpeg_quality_scaling(quality);
qualityarg = argv[argn];
} else if (keymatch(arg, "qslots", 2)) {
/* Quantization table slot numbers. */
@@ -382,7 +380,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
* default sampling factors.
*/
} else if (keymatch(arg, "scans", 2)) {
} else if (keymatch(arg, "scans", 4)) {
/* Set scan script. */
#ifdef C_MULTISCAN_FILES_SUPPORTED
if (++argn >= argc) /* advance to next argument */
@@ -422,11 +420,12 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
/* Set quantization tables for selected quality. */
/* Some or all may be overridden if -qtables is present. */
jpeg_set_quality(cinfo, quality, force_baseline);
if (qualityarg != NULL) /* process -quality if it was present */
if (! set_quality_ratings(cinfo, qualityarg, force_baseline))
usage();
if (qtablefile != NULL) /* process -qtables if it was present */
if (! read_quant_tables(cinfo, qtablefile,
q_scale_factor, force_baseline))
if (! read_quant_tables(cinfo, qtablefile, force_baseline))
usage();
if (qslotsarg != NULL) /* process -qslots if it was present */

View File

@@ -1,402 +0,0 @@
/*
* ckconfig.c
*
* Copyright (C) 1991-1994, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*/
/*
* This program is intended to help you determine how to configure the JPEG
* software for installation on a particular system. The idea is to try to
* compile and execute this program. If your compiler fails to compile the
* program, make changes as indicated in the comments below. Once you can
* compile the program, run it, and it will produce a "jconfig.h" file for
* your system.
*
* As a general rule, each time you try to compile this program,
* pay attention only to the *first* error message you get from the compiler.
* Many C compilers will issue lots of spurious error messages once they
* have gotten confused. Go to the line indicated in the first error message,
* and read the comments preceding that line to see what to change.
*
* Almost all of the edits you may need to make to this program consist of
* changing a line that reads "#define SOME_SYMBOL" to "#undef SOME_SYMBOL",
* or vice versa. This is called defining or undefining that symbol.
*/
/* First we must see if your system has the include files we need.
* We start out with the assumption that your system has all the ANSI-standard
* include files. If you get any error trying to include one of these files,
* undefine the corresponding HAVE_xxx symbol.
*/
#define HAVE_STDDEF_H /* replace 'define' by 'undef' if error here */
#ifdef HAVE_STDDEF_H /* next line will be skipped if you undef... */
#include <stddef.h>
#endif
#define HAVE_STDLIB_H /* same thing for stdlib.h */
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include <stdio.h> /* If you ain't got this, you ain't got C. */
/* We have to see if your string functions are defined by
* strings.h (old BSD convention) or string.h (everybody else).
* We try the non-BSD convention first; define NEED_BSD_STRINGS
* if the compiler says it can't find string.h.
*/
#undef NEED_BSD_STRINGS
#ifdef NEED_BSD_STRINGS
#include <strings.h>
#else
#include <string.h>
#endif
/* On some systems (especially older Unix machines), type size_t is
* defined only in the include file <sys/types.h>. If you get a failure
* on the size_t test below, try defining NEED_SYS_TYPES_H.
*/
#undef NEED_SYS_TYPES_H /* start by assuming we don't need it */
#ifdef NEED_SYS_TYPES_H
#include <sys/types.h>
#endif
/* Usually type size_t is defined in one of the include files we've included
* above. If not, you'll get an error on the "typedef size_t my_size_t;" line.
* In that case, first try defining NEED_SYS_TYPES_H just above.
* If that doesn't work, you'll have to search through your system library
* to figure out which include file defines "size_t". Look for a line that
* says "typedef something-or-other size_t;". Then, change the line below
* that says "#include <someincludefile.h>" to instead include the file
* you found size_t in, and define NEED_SPECIAL_INCLUDE. If you can't find
* type size_t anywhere, try replacing "#include <someincludefile.h>" with
* "typedef unsigned int size_t;".
*/
#undef NEED_SPECIAL_INCLUDE /* assume we DON'T need it, for starters */
#ifdef NEED_SPECIAL_INCLUDE
#include <someincludefile.h>
#endif
typedef size_t my_size_t; /* The payoff: do we have size_t now? */
/* The next question is whether your compiler supports ANSI-style function
* prototypes. You need to know this in order to choose between using
* makefile.ansi and using makefile.unix.
* The #define line below is set to assume you have ANSI function prototypes.
* If you get an error in this group of lines, undefine HAVE_PROTOTYPES.
*/
#define HAVE_PROTOTYPES
#ifdef HAVE_PROTOTYPES
int testfunction (int arg1, int * arg2); /* check prototypes */
struct methods_struct { /* check method-pointer declarations */
int (*error_exit) (char *msgtext);
int (*trace_message) (char *msgtext);
int (*another_method) (void);
};
int testfunction (int arg1, int * arg2) /* check definitions */
{
return arg2[arg1];
}
int test2function (void) /* check void arg list */
{
return 0;
}
#endif
/* Now we want to find out if your compiler knows what "unsigned char" means.
* If you get an error on the "unsigned char un_char;" line,
* then undefine HAVE_UNSIGNED_CHAR.
*/
#define HAVE_UNSIGNED_CHAR
#ifdef HAVE_UNSIGNED_CHAR
unsigned char un_char;
#endif
/* Now we want to find out if your compiler knows what "unsigned short" means.
* If you get an error on the "unsigned short un_short;" line,
* then undefine HAVE_UNSIGNED_SHORT.
*/
#define HAVE_UNSIGNED_SHORT
#ifdef HAVE_UNSIGNED_SHORT
unsigned short un_short;
#endif
/* Now we want to find out if your compiler understands type "void".
* If you get an error anywhere in here, undefine HAVE_VOID.
*/
#define HAVE_VOID
#ifdef HAVE_VOID
/* Caution: a C++ compiler will insist on complete prototypes */
typedef void * void_ptr; /* check void * */
#ifdef HAVE_PROTOTYPES /* check ptr to function returning void */
typedef void (*void_func) (int a, int b);
#else
typedef void (*void_func) ();
#endif
#ifdef HAVE_PROTOTYPES /* check void function result */
void test3function (void_ptr arg1, void_func arg2)
#else
void test3function (arg1, arg2)
void_ptr arg1;
void_func arg2;
#endif
{
char * locptr = (char *) arg1; /* check casting to and from void * */
arg1 = (void *) locptr;
(*arg2) (1, 2); /* check call of fcn returning void */
}
#endif
/* Now we want to find out if your compiler knows what "const" means.
* If you get an error here, undefine HAVE_CONST.
*/
#define HAVE_CONST
#ifdef HAVE_CONST
static const int carray[3] = {1, 2, 3};
#ifdef HAVE_PROTOTYPES
int test4function (const int arg1)
#else
int test4function (arg1)
const int arg1;
#endif
{
return carray[arg1];
}
#endif
/* If you get an error or warning about this structure definition,
* define INCOMPLETE_TYPES_BROKEN.
*/
#undef INCOMPLETE_TYPES_BROKEN
#ifndef INCOMPLETE_TYPES_BROKEN
typedef struct undefined_structure * undef_struct_ptr;
#endif
/* If you get an error about duplicate names,
* define NEED_SHORT_EXTERNAL_NAMES.
*/
#undef NEED_SHORT_EXTERNAL_NAMES
#ifndef NEED_SHORT_EXTERNAL_NAMES
int possibly_duplicate_function ()
{
return 0;
}
int possibly_dupli_function ()
{
return 1;
}
#endif
/************************************************************************
* OK, that's it. You should not have to change anything beyond this
* point in order to compile and execute this program. (You might get
* some warnings, but you can ignore them.)
* When you run the program, it will make a couple more tests that it
* can do automatically, and then it will create jconfig.h and print out
* any additional suggestions it has.
************************************************************************
*/
#ifdef HAVE_PROTOTYPES
int is_char_signed (int arg)
#else
int is_char_signed (arg)
int arg;
#endif
{
if (arg == 189) { /* expected result for unsigned char */
return 0; /* type char is unsigned */
}
else if (arg != -67) { /* expected result for signed char */
printf("Hmm, it seems 'char' is not eight bits wide on your machine.\n");
printf("I fear the JPEG software will not work at all.\n\n");
}
return 1; /* assume char is signed otherwise */
}
#ifdef HAVE_PROTOTYPES
int is_shifting_signed (long arg)
#else
int is_shifting_signed (arg)
long arg;
#endif
/* See whether right-shift on a long is signed or not. */
{
long res = arg >> 4;
if (res == -0x7F7E80CL) { /* expected result for signed shift */
return 1; /* right shift is signed */
}
/* see if unsigned-shift hack will fix it. */
/* we can't just test exact value since it depends on width of long... */
res |= (~0L) << (32-4);
if (res == -0x7F7E80CL) { /* expected result now? */
return 0; /* right shift is unsigned */
}
printf("Right shift isn't acting as I expect it to.\n");
printf("I fear the JPEG software will not work at all.\n\n");
return 0; /* try it with unsigned anyway */
}
#ifdef HAVE_PROTOTYPES
int main (int argc, char ** argv)
#else
int main (argc, argv)
int argc;
char ** argv;
#endif
{
char signed_char_check = (char) (-67);
FILE *outfile;
/* Attempt to write jconfig.h */
if ((outfile = fopen("jconfig.h", "w")) == NULL) {
printf("Failed to write jconfig.h\n");
return 1;
}
/* Write out all the info */
fprintf(outfile, "/* jconfig.h --- generated by ckconfig.c */\n");
fprintf(outfile, "/* see jconfig.doc for explanations */\n\n");
#ifdef HAVE_PROTOTYPES
fprintf(outfile, "#define HAVE_PROTOTYPES\n");
#else
fprintf(outfile, "#undef HAVE_PROTOTYPES\n");
#endif
#ifdef HAVE_UNSIGNED_CHAR
fprintf(outfile, "#define HAVE_UNSIGNED_CHAR\n");
#else
fprintf(outfile, "#undef HAVE_UNSIGNED_CHAR\n");
#endif
#ifdef HAVE_UNSIGNED_SHORT
fprintf(outfile, "#define HAVE_UNSIGNED_SHORT\n");
#else
fprintf(outfile, "#undef HAVE_UNSIGNED_SHORT\n");
#endif
#ifdef HAVE_VOID
fprintf(outfile, "/* #define void char */\n");
#else
fprintf(outfile, "#define void char\n");
#endif
#ifdef HAVE_CONST
fprintf(outfile, "/* #define const */\n");
#else
fprintf(outfile, "#define const\n");
#endif
if (is_char_signed((int) signed_char_check))
fprintf(outfile, "#undef CHAR_IS_UNSIGNED\n");
else
fprintf(outfile, "#define CHAR_IS_UNSIGNED\n");
#ifdef HAVE_STDDEF_H
fprintf(outfile, "#define HAVE_STDDEF_H\n");
#else
fprintf(outfile, "#undef HAVE_STDDEF_H\n");
#endif
#ifdef HAVE_STDLIB_H
fprintf(outfile, "#define HAVE_STDLIB_H\n");
#else
fprintf(outfile, "#undef HAVE_STDLIB_H\n");
#endif
#ifdef NEED_BSD_STRINGS
fprintf(outfile, "#define NEED_BSD_STRINGS\n");
#else
fprintf(outfile, "#undef NEED_BSD_STRINGS\n");
#endif
#ifdef NEED_SYS_TYPES_H
fprintf(outfile, "#define NEED_SYS_TYPES_H\n");
#else
fprintf(outfile, "#undef NEED_SYS_TYPES_H\n");
#endif
fprintf(outfile, "#undef NEED_FAR_POINTERS\n");
#ifdef NEED_SHORT_EXTERNAL_NAMES
fprintf(outfile, "#define NEED_SHORT_EXTERNAL_NAMES\n");
#else
fprintf(outfile, "#undef NEED_SHORT_EXTERNAL_NAMES\n");
#endif
#ifdef INCOMPLETE_TYPES_BROKEN
fprintf(outfile, "#define INCOMPLETE_TYPES_BROKEN\n");
#else
fprintf(outfile, "#undef INCOMPLETE_TYPES_BROKEN\n");
#endif
fprintf(outfile, "\n#ifdef JPEG_INTERNALS\n\n");
if (is_shifting_signed(-0x7F7E80B1L))
fprintf(outfile, "#undef RIGHT_SHIFT_IS_UNSIGNED\n");
else
fprintf(outfile, "#define RIGHT_SHIFT_IS_UNSIGNED\n");
fprintf(outfile, "\n#endif /* JPEG_INTERNALS */\n");
fprintf(outfile, "\n#ifdef JPEG_CJPEG_DJPEG\n\n");
fprintf(outfile, "#define BMP_SUPPORTED /* BMP image file format */\n");
fprintf(outfile, "#define GIF_SUPPORTED /* GIF image file format */\n");
fprintf(outfile, "#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */\n");
fprintf(outfile, "#undef RLE_SUPPORTED /* Utah RLE image file format */\n");
fprintf(outfile, "#define TARGA_SUPPORTED /* Targa image file format */\n\n");
fprintf(outfile, "#undef TWO_FILE_COMMANDLINE /* You may need this on non-Unix systems */\n");
fprintf(outfile, "#undef NEED_SIGNAL_CATCHER /* Define this if you use jmemname.c */\n");
fprintf(outfile, "#undef DONT_USE_B_MODE\n");
fprintf(outfile, "/* #define PROGRESS_REPORT */ /* optional */\n");
fprintf(outfile, "\n#endif /* JPEG_CJPEG_DJPEG */\n");
/* Close the jconfig.h file */
fclose(outfile);
/* User report */
printf("Configuration check for Independent JPEG Group's software done.\n");
printf("\nI have written the jconfig.h file for you.\n\n");
#ifdef HAVE_PROTOTYPES
printf("You should use makefile.ansi as the starting point for your Makefile.\n");
#else
printf("You should use makefile.unix as the starting point for your Makefile.\n");
#endif
#ifdef NEED_SPECIAL_INCLUDE
printf("\nYou'll need to change jconfig.h to include the system include file\n");
printf("that you found type size_t in, or add a direct definition of type\n");
printf("size_t if that's what you used. Just add it to the end.\n");
#endif
return 0;
}

3
cmakescripts/getdate.bat Normal file
View File

@@ -0,0 +1,3 @@
@echo off
for /f "tokens=1-4 eol=/ DELIMS=/ " %%i in ('date /t') do set BUILD=%%l%%j%%k
echo %BUILD%

View File

@@ -103,7 +103,7 @@ should be in the common data structures.
4. Don't use static variables except for read-only constant tables. Variables
that should be private to a module can be placed into private structures (see
the system architecture document, structure.doc).
the system architecture document, structure.txt).
5. Source file names should begin with "j" for files that are part of the
library proper; source files that are not part of the library, such as cjpeg.c

1731
configure vendored

File diff suppressed because it is too large Load Diff

295
configure.ac Normal file
View File

@@ -0,0 +1,295 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.56])
AC_INIT([libjpeg-turbo], [1.0.90])
BUILD=`date +%Y%m%d`
AM_INIT_AUTOMAKE([-Wall foreign dist-bzip2])
AC_PREFIX_DEFAULT(/opt/libjpeg-turbo)
# Always build with prototypes
AC_DEFINE([HAVE_PROTOTYPES], 1, [Define if your compiler supports prototypes])
# Checks for programs.
SAVED_CFLAGS=${CFLAGS}
SAVED_CXXFLAGS=${CXXFLAGS}
AC_PROG_CPP
AC_PROG_CC
AC_PROG_CXX
AC_PROG_INSTALL
AC_PROG_LIBTOOL
AC_PROG_LN_S
# Check whether compiler supports pointers to undefined structures
AC_MSG_CHECKING(whether compiler supports pointers to undefined structures)
AC_TRY_COMPILE([ typedef struct undefined_structure * undef_struct_ptr; ], ,
AC_MSG_RESULT(yes),
[AC_MSG_RESULT(no)
AC_DEFINE([INCOMPLETE_TYPES_BROKEN],[1],[Compiler does not support pointers to undefined structures.])])
if test "x${GCC}" = "xyes"; then
if test "x${SAVED_CFLAGS}" = "x"; then
CFLAGS=-O3
fi
if test "x${SAVED_CXXFLAGS}" = "x"; then
CXXFLAGS=-O3
fi
fi
AC_CHECK_DECL([__SUNPRO_C], [SUNCC="yes"], [SUNCC="no"])
if test "x${SUNCC}" = "xyes"; then
if test "x${SAVED_CFLAGS}" = "x"; then
CFLAGS=-xO5
fi
if test "x${SAVED_CXXFLAGS}" = "x"; then
CXXFLAGS=-xO5
fi
fi
# Checks for libraries.
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([stddef.h stdlib.h string.h])
AC_CHECK_HEADER([sys/types.h], AC_DEFINE([NEED_SYS_TYPES_H], 1, [Define if you have sys/types.h]))
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_C_CHAR_UNSIGNED
AC_C_INLINE
AC_TYPE_SIZE_T
AC_CHECK_TYPES([unsigned char, unsigned short])
AC_MSG_CHECKING([if right shift is signed])
AC_TRY_RUN(
[#include <stdio.h>
int is_shifting_signed (long arg) {
long res = arg >> 4;
if (res == -0x7F7E80CL)
return 1; /* right shift is signed */
/* see if unsigned-shift hack will fix it. */
/* we can't just test exact value since it depends on width of long... */
res |= (~0L) << (32-4);
if (res == -0x7F7E80CL)
return 0; /* right shift is unsigned */
printf("Right shift isn't acting as I expect it to.\n");
printf("I fear the JPEG software will not work at all.\n\n");
return 0; /* try it with unsigned anyway */
}
int main (void) {
exit(is_shifting_signed(-0x7F7E80B1L));
}],
[AC_MSG_RESULT(no)
AC_DEFINE([RIGHT_SHIFT_IS_UNSIGNED], 1, [Define if shift is unsigned])],
[AC_MSG_RESULT(yes)],
[AC_MSG_RESULT(Assuming that right shift is signed on target machine.)])
# test whether global names are unique to at least 15 chars
AC_MSG_CHECKING([for short external names])
AC_TRY_LINK(
[int possibly_duplicate_function () { return 0; }
int possibly_dupli_function () { return 1; }], [ ],
[AC_MSG_RESULT(ok)],
[AC_MSG_RESULT(short)
AC_DEFINE([NEED_SHORT_EXTERNAL_NAMES], 1, [Define if you need short function names])])
# Checks for library functions.
AC_CHECK_FUNCS([memset memcpy], [],
[AC_DEFINE([NEED_BSD_STRINGS], 1,
[Define if you have BSD-like bzero and bcopy])])
# Set flags to indicate platform
case "$host_os" in
cygwin* | mingw* | pw32* | interix*)
is_win32=1
;;
esac
AM_CONDITIONAL([IS_WIN32], [test "x$is_win32" = "x1"])
AC_MSG_CHECKING([libjpeg API version])
AC_ARG_VAR(JPEG_LIB_VERSION, [libjpeg API version (62, 70, or 80)])
if test "x$JPEG_LIB_VERSION" = "x"; then
AC_ARG_WITH([jpeg7],
AC_HELP_STRING([--with-jpeg7], [Emulate libjpeg v7 API/ABI (this makes libjpeg-turbo backward incompatible with libjpeg v6b.)]))
AC_ARG_WITH([jpeg8],
AC_HELP_STRING([--with-jpeg8], [Emulate libjpeg v8b API/ABI (this makes libjpeg-turbo backward incompatible with libjpeg v6b.)]))
if test "x${with_jpeg8}" = "xyes"; then
JPEG_LIB_VERSION=80
else
if test "x${with_jpeg7}" = "xyes"; then
JPEG_LIB_VERSION=70
else
JPEG_LIB_VERSION=62
fi
fi
fi
JPEG_LIB_VERSION_DECIMAL=`expr $JPEG_LIB_VERSION / 10`.`expr $JPEG_LIB_VERSION % 10`
AC_SUBST(JPEG_LIB_VERSION_DECIMAL)
AC_MSG_RESULT([$JPEG_LIB_VERSION_DECIMAL])
AC_DEFINE_UNQUOTED(JPEG_LIB_VERSION, [$JPEG_LIB_VERSION], [libjpeg API version])
AC_MSG_CHECKING([libjpeg shared library version])
AC_ARG_VAR(SO_MAJOR_VERSION, [Major version of the libjpeg-turbo shared library (default is determined by the API version)])
AC_ARG_VAR(SO_MINOR_VERSION, [Minor version of the libjpeg-turbo shared library (default is determined by the API version)])
if test "x$SO_MAJOR_VERSION" = "x"; then
case "$JPEG_LIB_VERSION" in
62) SO_MAJOR_VERSION=$JPEG_LIB_VERSION ;;
*) SO_MAJOR_VERSION=`expr $JPEG_LIB_VERSION / 10` ;;
esac
fi
if test "x$SO_MINOR_VERSION" = "x"; then
case "$JPEG_LIB_VERSION" in
80) SO_MINOR_VERSION=2 ;;
*) SO_MINOR_VERSION=0 ;;
esac
fi
AC_MSG_RESULT([$SO_MAJOR_VERSION:$SO_MINOR_VERSION])
AC_SUBST(SO_MAJOR_VERSION)
AC_SUBST(SO_MINOR_VERSION)
VERSION_SCRIPT=yes
AC_ARG_ENABLE([ld-version-script],
AS_HELP_STRING([--disable-ld-version-script],
[Disable linker version script for libjpeg-turbo (default is to use linker version script if the linker supports it)]),
[VERSION_SCRIPT=$enableval], [])
AC_MSG_CHECKING([whether the linker supports version scripts])
SAVED_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS -Wl,--version-script,conftest.map"
cat > conftest.map <<EOF
VERS_1 {
global: *;
};
EOF
AC_LINK_IFELSE(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([], []),
[VERSION_SCRIPT_FLAG=-Wl,-M,; AC_MSG_RESULT([yes (Sun style)])], [])
fi
if test "x$VERSION_SCRIPT_FLAG" = "x"; then
VERSION_SCRIPT=no
AC_MSG_RESULT(no)
fi
ANON_VERSION_SCRIPT=yes
AC_MSG_CHECKING([whether the linker supports anonymous version scripts])
LDFLAGS="$SAVED_LDFLAGS -Wl,--version-script,conftest.map"
cat > conftest.map <<EOF
{
global: main;
local: *;
};
EOF
AC_LINK_IFELSE(AC_LANG_PROGRAM([], []),
[ANON_VERSION_SCRIPT_FLAG=-Wl,--version-script,; AC_MSG_RESULT([yes (GNU style)])], [])
if test "x$ANON_VERSION_SCRIPT_FLAG" = "x"; then
LDFLAGS="$SAVED_LDFLAGS -Wl,-M,conftest.map"
AC_LINK_IFELSE(AC_LANG_PROGRAM([], []),
[ANON_VERSION_SCRIPT_FLAG=-Wl,-M,; AC_MSG_RESULT([yes (Sun style)])], [])
fi
if test "x$ANON_VERSION_SCRIPT_FLAG" = "x"; then
ANON_VERSION_SCRIPT=no
AC_MSG_RESULT(no)
fi
LDFLAGS="$SAVED_LDFLAGS"
AC_MSG_CHECKING([whether to use version script when building libjpeg])
AC_MSG_RESULT($VERSION_SCRIPT)
AM_CONDITIONAL(VERSION_SCRIPT, test "x$VERSION_SCRIPT" = "xyes")
AM_CONDITIONAL(ANON_VERSION_SCRIPT, test "x$ANON_VERSION_SCRIPT" = "xyes")
AC_SUBST(VERSION_SCRIPT_FLAG)
AC_SUBST(ANON_VERSION_SCRIPT_FLAG)
AC_MSG_CHECKING([whether to include arithmetic encoding support])
AC_ARG_WITH([arith-enc],
AC_HELP_STRING([--without-arith-enc], [Omit arithmetic encoding support]))
if test "x$with_arith_enc" = "xno"; then
AC_MSG_RESULT(no)
else
AC_DEFINE([C_ARITH_CODING_SUPPORTED], [1], [Support arithmetic encoding])
AC_MSG_RESULT(yes)
fi
AM_CONDITIONAL([WITH_ARITH_ENC], [test "x$with_arith_enc" != "xno"])
AC_MSG_CHECKING([whether to include arithmetic decoding support])
AC_ARG_WITH([arith-dec],
AC_HELP_STRING([--without-arith-dec], [Omit arithmetic decoding support]))
if test "x$with_arith_dec" = "xno"; then
AC_MSG_RESULT(no)
else
AC_DEFINE([D_ARITH_CODING_SUPPORTED], [1], [Support arithmetic decoding])
AC_MSG_RESULT(yes)
fi
AM_CONDITIONAL([WITH_ARITH_DEC], [test "x$with_arith_dec" != "xno"])
AM_CONDITIONAL([WITH_ARITH], [test "x$with_arith_dec" != "xno" -o "x$with_arith_enc" != "xno"])
# SIMD is optional
AC_ARG_WITH([simd],
AC_HELP_STRING([--without-simd],[Omit accelerated SIMD routines.]))
if test "x${with_simd}" != "xno"; then
# Check if we're on a supported CPU
AC_MSG_CHECKING([if we have SIMD optimisations for cpu type])
case "$host_cpu" in
x86_64 | amd64)
AC_MSG_RESULT([yes (x86_64)])
AC_PROG_NASM
simd_arch=x86_64
;;
i*86 | x86 | ia32)
AC_MSG_RESULT([yes (i386)])
AC_PROG_NASM
simd_arch=i386
;;
*)
AC_MSG_RESULT([no ("$host_cpu")])
AC_MSG_WARN([SIMD support not available for this CPU. Performance will suffer.])
with_simd=no;
;;
esac
if test "x${with_simd}" != "xno"; then
AC_DEFINE([WITH_SIMD], [1], [Use accelerated SIMD routines.])
fi
fi
AM_CONDITIONAL([WITH_SIMD], [test "x$with_simd" != "xno"])
AM_CONDITIONAL([SIMD_I386], [test "x$simd_arch" = "xi386"])
AM_CONDITIONAL([SIMD_X86_64], [test "x$simd_arch" = "xx86_64"])
AM_CONDITIONAL([X86_64], [test "x$host_cpu" = "xx86_64" -o "x$host_cpu" = "xamd64"])
case "$host_cpu" in
x86_64)
RPMARCH=x86_64
DEBARCH=amd64
;;
i*86 | x86 | ia32)
RPMARCH=i386
DEBARCH=i386
;;
esac
AC_SUBST(RPMARCH)
AC_SUBST(DEBARCH)
AC_SUBST(BUILD)
AC_DEFINE_UNQUOTED([BUILD], "$BUILD", [Build number])
# jconfig.h is the file we use, but we have another before that to
# fool autoheader. the reason is that we include this header in our
# API headers, which can screw things up for users of the lib.
# jconfig.h is a minimal version that allows this package to be built
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_HEADERS([jconfig.h])
AC_CONFIG_FILES([libjpeg-turbo.spec:release/libjpeg-turbo.spec.in])
AC_CONFIG_FILES([makemacpkg:release/makemacpkg.in])
AC_CONFIG_FILES([makesunpkg:release/makesunpkg.in])
AC_CONFIG_FILES([libjpeg.map])
AC_CONFIG_FILES([Makefile simd/Makefile])
AC_OUTPUT

21
djpeg.1
View File

@@ -1,4 +1,4 @@
.TH DJPEG 1 "15 June 1995"
.TH DJPEG 1 "11 October 2010"
.SH NAME
djpeg \- decompress a JPEG file to an image file
.SH SYNOPSIS
@@ -26,9 +26,9 @@ or
.BR \-gr .
Most of the "basic" switches can be abbreviated to as little as one letter.
Upper and lower case are equivalent (thus
.B \-GIF
.B \-BMP
is the same as
.BR \-gif ).
.BR \-bmp ).
British spellings are also accepted (e.g.,
.BR \-greyscale ),
though for brevity these are not mentioned below.
@@ -182,13 +182,13 @@ Same as
.BR \-verbose .
.SH EXAMPLES
.LP
This example decompresses the JPEG file foo.jpg, automatically quantizes to
256 colors, and saves the output in GIF format in foo.gif:
This example decompresses the JPEG file foo.jpg, quantizes it to
256 colors, and saves the output in 8-bit BMP format in foo.bmp:
.IP
.B djpeg \-gif
.B djpeg \-colors 256 \-bmp
.I foo.jpg
.B >
.I foo.gif
.I foo.bmp
.SH HINTS
To get a quick preview of an image, use the
.B \-grayscale
@@ -243,6 +243,7 @@ Communications of the ACM, April 1991 (vol. 34, no. 4), pp. 30-44.
.SH AUTHOR
Independent JPEG Group
.SH BUGS
Arithmetic coding is not supported for legal reasons.
.PP
Still not as fast as we'd like.
To avoid the Unisys LZW patent,
.B djpeg
produces uncompressed GIF files. These are larger than they should be, but
are readable by standard GIF decoders.

35
djpeg.c
View File

@@ -1,7 +1,8 @@
/*
* djpeg.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Copyright (C) 1991-1997, Thomas G. Lane.
* Copyright (C) 2010, 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.
*
@@ -25,6 +26,7 @@
#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
#include "jversion.h" /* for version message */
#include "config.h"
#include <ctype.h> /* to declare isprint() */
@@ -240,7 +242,10 @@ parse_switches (j_decompress_ptr cinfo, int argc, char **argv,
static boolean printed_version = FALSE;
if (! printed_version) {
fprintf(stderr, "Independent JPEG Group's DJPEG, version %s\n%s\n",
fprintf(stderr, "%s version %s (build %s)\n",
PACKAGE_NAME, VERSION, BUILD);
fprintf(stderr, "%s\n\n", LJTCOPYRIGHT);
fprintf(stderr, "Based on Independent JPEG Group's libjpeg, version %s\n%s\n\n",
JVERSION, JCOPYRIGHT);
printed_version = TRUE;
}
@@ -344,9 +349,9 @@ parse_switches (j_decompress_ptr cinfo, int argc, char **argv,
/*
* Marker processor for COM markers.
* Marker processor for COM and interesting APPn markers.
* This replaces the library's built-in processor, which just skips the marker.
* We want to print out the marker as text, if possible.
* We want to print out the marker as text, to the extent possible.
* Note this code relies on a non-suspending data source.
*/
@@ -366,7 +371,7 @@ jpeg_getc (j_decompress_ptr cinfo)
METHODDEF(boolean)
COM_handler (j_decompress_ptr cinfo)
print_text_marker (j_decompress_ptr cinfo)
{
boolean traceit = (cinfo->err->trace_level >= 1);
INT32 length;
@@ -377,8 +382,13 @@ COM_handler (j_decompress_ptr cinfo)
length += jpeg_getc(cinfo);
length -= 2; /* discount the length word itself */
if (traceit)
fprintf(stderr, "Comment, length %ld:\n", (long) length);
if (traceit) {
if (cinfo->unread_marker == JPEG_COM)
fprintf(stderr, "Comment, length %ld:\n", (long) length);
else /* assume it is an APPn otherwise */
fprintf(stderr, "APP%d, length %ld:\n",
cinfo->unread_marker - JPEG_APP0, (long) length);
}
while (--length >= 0) {
ch = jpeg_getc(cinfo);
@@ -445,8 +455,15 @@ main (int argc, char **argv)
jerr.addon_message_table = cdjpeg_message_table;
jerr.first_addon_message = JMSG_FIRSTADDONCODE;
jerr.last_addon_message = JMSG_LASTADDONCODE;
/* Insert custom COM marker processor. */
jpeg_set_marker_processor(&cinfo, JPEG_COM, COM_handler);
/* Insert custom marker processor for COM and APP12.
* APP12 is used by some digital camera makers for textual info,
* so we provide the ability to display it as text.
* If you like, additional APPn marker types can be selected for display,
* but don't try to override APP0 or APP14 this way (see libjpeg.txt).
*/
jpeg_set_marker_processor(&cinfo, JPEG_COM, print_text_marker);
jpeg_set_marker_processor(&cinfo, JPEG_APP0+12, print_text_marker);
/* Now safe to enable signal catcher. */
#ifdef NEED_SIGNAL_CATCHER

View File

@@ -3,7 +3,7 @@
*
* This file illustrates how to use the IJG code as a subroutine library
* to read or write JPEG image files. You should look at this code in
* conjunction with the documentation file libjpeg.doc.
* conjunction with the documentation file libjpeg.txt.
*
* This code will not do anything useful as-is, but it may be helpful as a
* skeleton for constructing routines that call the JPEG library.
@@ -196,7 +196,7 @@ write_JPEG_file (char * filename, int quality)
* files for anything that doesn't fit within the maximum-memory setting.
* (Note that temp files are NOT needed if you use the default parameters.)
* On some systems you may need to set up a signal handler to ensure that
* temporary files are deleted if the program is interrupted. See libjpeg.doc.
* temporary files are deleted if the program is interrupted. See libjpeg.txt.
*
* Scanlines MUST be supplied in top-to-bottom order if you want your JPEG
* files to be compatible with everyone else's. If you cannot readily read
@@ -335,7 +335,7 @@ read_JPEG_file (char * filename)
/* We can ignore the return value from jpeg_read_header since
* (a) suspension is not possible with the stdio data source, and
* (b) we passed TRUE to reject a tables-only JPEG file as an error.
* See libjpeg.doc for more info.
* See libjpeg.txt for more info.
*/
/* Step 4: set parameters for decompression */
@@ -413,14 +413,14 @@ read_JPEG_file (char * filename)
* In the above code, we ignored the return value of jpeg_read_scanlines,
* which is the number of scanlines actually read. We could get away with
* this because we asked for only one line at a time and we weren't using
* a suspending data source. See libjpeg.doc for more info.
* a suspending data source. See libjpeg.txt for more info.
*
* We cheated a bit by calling alloc_sarray() after jpeg_start_decompress();
* we should have done it beforehand to ensure that the space would be
* counted against the JPEG max_memory setting. In some systems the above
* code would risk an out-of-memory error. However, in general we don't
* know the output image dimensions before jpeg_start_decompress(), unless we
* call jpeg_calc_output_dimensions(). See libjpeg.doc for more about this.
* call jpeg_calc_output_dimensions(). See libjpeg.txt for more about this.
*
* Scanlines are returned in the same order as they appear in the JPEG file,
* which is standardly top-to-bottom. If you must emit data bottom-to-top,
@@ -429,5 +429,5 @@ read_JPEG_file (char * filename)
*
* As with compression, some operating modes may require temporary files.
* On some systems you may need to set up a signal handler to ensure that
* temporary files are deleted if the program is interrupted. See libjpeg.doc.
* temporary files are deleted if the program is interrupted. See libjpeg.txt.
*/

View File

@@ -1,6 +1,6 @@
IJG JPEG LIBRARY: FILE LIST
Copyright (C) 1994-1996, Thomas G. Lane.
Copyright (C) 1994-2010, Thomas G. Lane, Guido Vollbeding, 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.
@@ -74,8 +74,9 @@ jfdctfst.c Forward DCT using faster, less accurate integer method.
jfdctflt.c Forward DCT using floating-point arithmetic.
jchuff.c Huffman entropy coding for sequential JPEG.
jcphuff.c Huffman entropy coding for progressive JPEG.
jcarith.c Arithmetic entropy coding.
jcmarker.c JPEG marker writing.
jdatadst.c Data destination manager for stdio output.
jdatadst.c Data destination managers for memory and stdio output.
Decompression side of the library:
@@ -87,6 +88,7 @@ jdpostct.c Postprocessor buffer controller.
jdmarker.c JPEG marker reading.
jdhuff.c Huffman entropy decoding for sequential JPEG.
jdphuff.c Huffman entropy decoding for progressive JPEG.
jdarith.c Arithmetic entropy decoding.
jddctmgr.c IDCT manager (IDCT implementation selection & control).
jidctint.c Inverse DCT using slow-but-accurate integer method.
jidctfst.c Inverse DCT using faster, less accurate integer method.
@@ -98,10 +100,12 @@ jdmerge.c Merged upsampling/color conversion (faster, lower quality).
jquant1.c One-pass color quantization using a fixed-spacing colormap.
jquant2.c Two-pass color quantization using a custom-generated colormap.
Also handles one-pass quantization to an externally given map.
jdatasrc.c Data source manager for stdio input.
jdatasrc.c Data source managers for memory and stdio input.
Support files for both compression and decompression:
jaricom.c Tables for common use in arithmetic entropy encoding and
decoding routines.
jerror.c Standard error handling routines (application replaceable).
jmemmgr.c System-independent (more or less) memory management code.
jutils.c Miscellaneous utility routines.
@@ -113,12 +117,12 @@ module:
jmemnobs.c "No backing store": assumes adequate virtual memory exists.
jmemansi.c Makes temporary files with ANSI-standard routine tmpfile().
jmemname.c Makes temporary files with program-generated file names.
jmemdos.c Custom implementation for MS-DOS: knows about extended and
expanded memory as well as temporary files.
jmemdos.c Custom implementation for MS-DOS (16-bit environment only):
can use extended and expanded memory as well as temp files.
jmemmac.c Custom implementation for Apple Macintosh.
Exactly one of the system-dependent modules should be configured into an
installed JPEG library (see install.doc for hints about which one to use).
installed JPEG library (see install.txt for hints about which one to use).
On unusual systems you may find it worthwhile to make a special
system-dependent memory manager.
@@ -134,8 +138,9 @@ CJPEG/DJPEG/JPEGTRAN
Include files:
cdjpeg.h Declarations shared by cjpeg/djpeg modules.
cderror.h Additional error and trace message codes for cjpeg/djpeg.
cdjpeg.h Declarations shared by cjpeg/djpeg/jpegtran modules.
cderror.h Additional error and trace message codes for cjpeg et al.
transupp.h Declarations for jpegtran support routines in transupp.c.
C source code files:
@@ -146,11 +151,12 @@ cdjpeg.c Utility routines used by all three programs.
rdcolmap.c Code to read a colormap file for djpeg's "-map" switch.
rdswitch.c Code to process some of cjpeg's more complex switches.
Also used by jpegtran.
transupp.c Support code for jpegtran: lossless image manipulations.
Image file reader modules for cjpeg:
rdbmp.c BMP file input.
rdgif.c GIF file input.
rdgif.c GIF file input (now just a stub).
rdppm.c PPM/PGM file input.
rdrle.c Utah RLE file input.
rdtarga.c Targa file input.
@@ -158,7 +164,7 @@ rdtarga.c Targa file input.
Image file writer modules for djpeg:
wrbmp.c BMP file output.
wrgif.c GIF file output.
wrgif.c GIF file output (a mere shadow of its former self).
wrppm.c PPM/PGM file output.
wrrle.c Utah RLE file output.
wrtarga.c Targa file output.
@@ -182,22 +188,27 @@ ADDITIONAL FILES
Documentation (see README for a guide to the documentation files):
README Master documentation file.
*.doc Other documentation files.
*.txt Other documentation files.
*.1 Documentation in Unix man page format.
change.log Version-to-version change highlights.
example.c Sample code for calling JPEG library.
Configuration/installation files and programs (see install.doc for more info):
Configuration/installation files and programs (see install.txt for more info):
configure Unix shell script to perform automatic configuration.
ckconfig.c Program to generate jconfig.h on non-Unix systems.
jconfig.doc Template for making jconfig.h by hand.
makefile.* Sample makefiles for particular systems.
jconfig.* Sample jconfig.h for particular systems.
ansi2knr.c De-ANSIfier for pre-ANSI C compilers (courtesy of
L. Peter Deutsch and Aladdin Enterprises).
configure.ac Source file for use with Autoconf to generate configure.
ltmain.sh Support scripts for configure (from GNU libtool).
config.guess
config.sub
depcomp
missing
install-sh Install shell script for those Unix systems lacking one.
Makefile.in Makefile input for configure.
Makefile.am Source file for use with Automake to generate Makefile.in.
jconfig.txt Template for making jconfig.h by hand.
aclocal.m4 M4 macro definitions for use with Autoconf.
Test files (see install.doc for test procedure):
Test files (see install.txt for test procedure):
test*.* Source and comparison files for confidence test.
These are binary image files, NOT text files.

View File

@@ -1,6 +1,6 @@
INSTALLATION INSTRUCTIONS for the Independent JPEG Group's JPEG software
Copyright (C) 1991-1996, Thomas G. Lane.
Copyright (C) 1991-2010, Thomas G. Lane, Guido Vollbeding.
This file is part of the Independent JPEG Group's software.
For conditions of distribution and use, see the accompanying README file.
@@ -94,6 +94,14 @@ Configure was created with GNU Autoconf and it follows the usual conventions
for GNU configure scripts. It makes a few assumptions that you may want to
override. You can do this by providing optional switches to configure:
* Configure will build both static and shared libraries, if possible.
If you want to build libjpeg only as a static library, say
./configure --disable-shared
If you want to build libjpeg only as a shared library, say
./configure --disable-static
Configure uses GNU libtool to take care of system-dependent shared library
building methods.
* Configure will use gcc (GNU C compiler) if it's available, otherwise cc.
To force a particular compiler to be selected, use the CC option, for example
./configure CC='cc'
@@ -102,8 +110,10 @@ For example, on HP-UX you probably want to say
./configure CC='cc -Aa'
to get HP's compiler to run in ANSI mode.
* The default CFLAGS setting is "-O". You can override this by saying,
for example, ./configure CFLAGS='-O2'.
* The default CFLAGS setting is "-g" for non-gcc compilers, "-g -O2" for gcc.
You can override this by saying, for example,
./configure CFLAGS='-O2'
if you want to compile without debugging support.
* Configure will set up the makefile so that "make install" will install files
into /usr/local/bin, /usr/local/man, etc. You can specify an installation
@@ -131,25 +141,29 @@ Makefile jconfig file System and/or compiler
makefile.manx jconfig.manx Amiga, Manx Aztec C
makefile.sas jconfig.sas Amiga, SAS C
makeproj.mac jconfig.mac Apple Macintosh, Metrowerks CodeWarrior
mak*jpeg.st jconfig.st Atari ST/STE/TT, Pure C or Turbo C
makefile.bcc jconfig.bcc MS-DOS or OS/2, Borland C
makefile.dj jconfig.dj MS-DOS, DJGPP (Delorie's port of GNU C)
makefile.mc6 jconfig.mc6 MS-DOS, Microsoft C version 6.x and up
makefile.mc6 jconfig.mc6 MS-DOS, Microsoft C (16-bit only)
makefile.wat jconfig.wat MS-DOS, OS/2, or Windows NT, Watcom C
makefile.vc jconfig.vc Windows NT/95, MS Visual C++
make*.vc6 jconfig.vc Windows NT/95, MS Visual C++ 6
make*.v10 jconfig.vc Windows NT/95, MS Visual C++ 2010 (v10)
makefile.mms jconfig.vms Digital VMS, with MMS software
makefile.vms jconfig.vms Digital VMS, without MMS software
Copy the proper jconfig file to jconfig.h and the makefile to Makefile
(or whatever your system uses as the standard makefile name). For the
Atari, we provide four project files; see the Atari hints below.
Copy the proper jconfig file to jconfig.h and the makefile to Makefile (or
whatever your system uses as the standard makefile name). For more info see
the appropriate system-specific hints section near the end of this file.
Configuring the software by hand
--------------------------------
First, generate a jconfig.h file. If you are moderately familiar with C,
the comments in jconfig.doc should be enough information to do this; just
copy jconfig.doc to jconfig.h and edit it appropriately. Otherwise, you may
the comments in jconfig.txt should be enough information to do this; just
copy jconfig.txt to jconfig.h and edit it appropriately. Otherwise, you may
prefer to use the ckconfig.c program. You will need to compile and execute
ckconfig.c by hand --- we hope you know at least enough to do that.
ckconfig.c may not compile the first try (in fact, the whole idea is for it
@@ -303,7 +317,7 @@ As a quick test of functionality we've included a small sample image in
several forms:
testorig.jpg Starting point for the djpeg tests.
testimg.ppm The output of djpeg testorig.jpg
testimg.gif The output of djpeg -gif testorig.jpg
testimg.bmp The output of djpeg -bmp -colors 256 testorig.jpg
testimg.jpg The output of cjpeg testimg.ppm
testprog.jpg Progressive-mode equivalent of testorig.jpg.
testimgp.jpg The output of cjpeg -progressive -optimize testimg.ppm
@@ -339,10 +353,10 @@ check fails, try recompiling with USE_SETMODE or USE_FDOPEN defined.
If it still doesn't work, better use two-file style.
If you chose a memory manager other than jmemnobs.c, you should test that
temporary-file usage works. Try "djpeg -gif -max 0 testorig.jpg" and make
sure its output matches testimg.gif. If you have any really large images
handy, try compressing them with -optimize and/or decompressing with -gif to
make sure your DEFAULT_MAX_MEM setting is not too large.
temporary-file usage works. Try "djpeg -bmp -colors 256 -max 0 testorig.jpg"
and make sure its output matches testimg.bmp. If you have any really large
images handy, try compressing them with -optimize and/or decompressing with
-colors 256 to make sure your DEFAULT_MAX_MEM setting is not too large.
NOTE: this is far from an exhaustive test of the JPEG software; some modules,
such as 1-pass color quantization, are not exercised at all. It's just a
@@ -357,7 +371,7 @@ Once you're done with the above steps, you can install the software by
copying the executable files (cjpeg, djpeg, jpegtran, rdjpgcom, and wrjpgcom)
to wherever you normally install programs. On Unix systems, you'll also want
to put the man pages (cjpeg.1, djpeg.1, jpegtran.1, rdjpgcom.1, wrjpgcom.1)
in the man-page directory. The canned makefiles don't support this step
in the man-page directory. The pre-fab makefiles don't support this step
since there's such a wide variety of installation procedures on different
systems.
@@ -370,8 +384,13 @@ to see where configure thought the files should go. You may need to edit
the Makefile, particularly if your system's conventions for man page
filenames don't match what configure expects.
If you want to install the library file libjpeg.a and the include files j*.h
(for use in compiling other programs besides the IJG ones), then say
If you want to install the IJG library itself, for use in compiling other
programs besides ours, then you need to put the four include files
jpeglib.h jerror.h jconfig.h jmorecfg.h
into your include-file directory, and put the library file libjpeg.a
(extension may vary depending on system) wherever library files go.
If you generated a Makefile with "configure", it will do what it thinks
is the right thing if you say
make install-lib
@@ -424,10 +443,10 @@ on our to-do list.)
The PPM reader (rdppm.c) can read 12-bit data from either text-format or
binary-format PPM and PGM files. Binary-format PPM/PGM files which have a
maxval greater than 255 are assumed to use 2 bytes per sample, LSB first
(little-endian order). As of early 1995, 2-byte binary format is not
officially supported by the PBMPLUS library, but it is expected that the
next release of PBMPLUS will support it. Note that the PPM reader will
maxval greater than 255 are assumed to use 2 bytes per sample, MSB first
(big-endian order). As of early 1995, 2-byte binary format is not
officially supported by the PBMPLUS library, but it is expected that a
future release of PBMPLUS will support it. Note that the PPM reader will
read files of any maxval regardless of the BITS_IN_JSAMPLE setting; incoming
data is automatically rescaled to either maxval=255 or maxval=4095 as
appropriate for the cjpeg bit depth.
@@ -498,7 +517,7 @@ that float DCT results may vary slightly across machines.) To do that, add
"#define JDCT_DEFAULT JDCT_FLOAT" to jconfig.h. Even if you don't change
the default, you should redefine JDCT_FASTEST, which is the method selected
by djpeg's -fast switch. Don't forget to update the documentation files
(usage.doc and/or cjpeg.1, djpeg.1) to agree with what you've done.
(usage.txt and/or cjpeg.1, djpeg.1) to agree with what you've done.
If access to "short" arrays is slow on your machine, it may be a win to
define type JCOEF as int rather than short. This will cost a good deal of
@@ -515,17 +534,17 @@ In general, it's worth trying the maximum optimization level of your compiler,
and experimenting with any optional optimizations such as loop unrolling.
(Unfortunately, far too many compilers have optimizer bugs ... be prepared to
back off if the code fails self-test.) If you do any experimentation along
these lines, please report the optimal settings to jpeg-info@uunet.uu.net so
we can mention them in future releases. Be sure to specify your machine and
compiler version.
these lines, please report the optimal settings to jpeg-info@uc.ag so we
can mention them in future releases. Be sure to specify your machine
and compiler version.
HINTS FOR SPECIFIC SYSTEMS
==========================
We welcome reports on changes needed for systems not mentioned here. Submit
'em to jpeg-info@uunet.uu.net. Also, if configure or ckconfig.c is wrong
about how to configure the JPEG software for your system, please let us know.
'em to jpeg-info@uc.ag. Also, if configure or ckconfig.c is wrong about how
to configure the JPEG software for your system, please let us know.
Acorn RISC OS:
@@ -545,7 +564,7 @@ Also add a new line '.c.o:; $(cc) $< $(cflags) -c -o $@'. Remove the
lines '$(RM) libjpeg.o' and '$(AR2) libjpeg.o' and the 'jconfig.h'
dependency section.
Copy jconfig.doc to jconfig.h. Edit jconfig.h to define TWO_FILE_COMMANDLINE
Copy jconfig.txt to jconfig.h. Edit jconfig.h to define TWO_FILE_COMMANDLINE
and CHAR_IS_UNSIGNED.
Run the makefile using !AMU not !Make. If you want to use the 'clean' and
@@ -564,30 +583,31 @@ manager, with temporary files being created on the device named by
Atari ST/STE/TT:
Copy the project files makcjpeg.st, makdjpeg.st, maktjpeg.st, and makljpeg.st
to cjpeg.prj, djpeg.prj, jpegtran.prj, and libjpeg.prj respectively. The
project files should work as-is with Pure C. For Turbo C, change library
filenames "PC..." to "TC..." in each project file. Note that libjpeg.prj
filenames "pc..." to "tc..." in each project file. Note that libjpeg.prj
selects jmemansi.c as the recommended memory manager. You'll probably want to
adjust the DEFAULT_MAX_MEM setting --- you want it to be a couple hundred K
less than your normal free memory. Put "#define DEFAULT_MAX_MEM nnnn" into
jconfig.h to do this.
To use the 68881/68882 coprocessor for the floating point DCT, add the
compiler option "-8" to the project files and replace PCFLTLIB.LIB with
PC881LIB.LIB in cjpeg.prj and djpeg.prj. Or if you don't have a
compiler option "-8" to the project files and replace pcfltlib.lib with
pc881lib.lib in cjpeg.prj and djpeg.prj. Or if you don't have a
coprocessor, you may prefer to remove the float DCT code by undefining
DCT_FLOAT_SUPPORTED in jmorecfg.h (since without a coprocessor, the float
code will be too slow to be useful). In that case, you can delete
PCFLTLIB.LIB from the project files.
pcfltlib.lib from the project files.
Note that you must make libjpeg.lib before making cjpeg.ttp, djpeg.ttp,
or jpegtran.ttp. You'll have to perform the self-test by hand.
We haven't bothered to include project files for rdjpgcom and wrjpgcom.
Those source files should just be compiled by themselves; they don't
depend on the JPEG library.
depend on the JPEG library. You can use the default.prj project file
of the Pure C distribution to make the programs.
There is a bug in some older versions of the Turbo C library which causes the
space used by temporary files created with "tmpfile()" not to be freed after
@@ -637,49 +657,62 @@ provide a Unix-style command line interface. You can use this interface on
the Mac by means of the ccommand() library routine provided by Metrowerks
CodeWarrior or Think C. This is only appropriate for testing the library,
however; to make a user-friendly equivalent of cjpeg/djpeg you'd really want
to develop a Mac-style user interface. Such an interface exists for pre-v5
IJG libraries (see the Think C entry, below) but at this writing it has not
been updated to work with the current release.
to develop a Mac-style user interface. There isn't a complete example
available at the moment, but there are some helpful starting points:
1. Sam Bushell's free "To JPEG" applet provides drag-and-drop conversion to
JPEG under System 7 and later. This only illustrates how to use the
compression half of the library, but it does a very nice job of that part.
The CodeWarrior source code is available from http://www.pobox.com/~jsam.
2. Jim Brunner prepared a Mac-style user interface for both compression and
decompression. Unfortunately, it hasn't been updated since IJG v4, and
the library's API has changed considerably since then. Still it may be of
some help, particularly as a guide to compiling the IJG code under Think C.
Jim's code is available from the Info-Mac archives, at sumex-aim.stanford.edu
or mirrors thereof; see file /info-mac/dev/src/jpeg-convert-c.hqx.
We recommend replacing "malloc" and "free" by "NewPtr" and "DisposePtr" in
whichever memory manager back end you use, because Mac C libraries often
have inferior implementations of malloc/free. jmemmac.c is recommended;
it is a customized version of jmemansi.c with this change and a Mac-specific
implementation of jpeg_mem_available(). You can also use jmemnobs.c if you
don't care about handling images larger than available memory.
jmemmac.c is the recommended memory manager back end for Macintosh. It uses
NewPtr/DisposePtr instead of malloc/free, and has a Mac-specific
implementation of jpeg_mem_available(). It also creates temporary files that
follow Mac conventions. (That part of the code relies on System-7-or-later OS
functions. See the comments in jmemmac.c if you need to run it on System 6.)
NOTE that USE_MAC_MEMMGR must be defined in jconfig.h to use jmemmac.c.
Macintosh, MPW:
We don't directly support MPW in the current release, but Larry Rosenstein
ported an earlier version of the IJG code without very much trouble. There's
useful notes and conversion scripts in his kit for porting PBMPLUS to MPW.
You can obtain the kit by FTP to ftp.apple.com, files /pub/lsr/pbmplus-port*.
You can also use jmemnobs.c, if you don't care about handling images larger
than available memory. If you use any memory manager back end other than
jmemmac.c, we recommend replacing "malloc" and "free" by "NewPtr" and
"DisposePtr", because Mac C libraries often have peculiar implementations of
malloc/free. (For instance, free() may not return the freed space to the
Mac Memory Manager. This is undesirable for the IJG code because jmemmgr.c
already clumps space requests.)
Macintosh, Metrowerks CodeWarrior:
Metrowerks release DR2 has problems with the IJG code; don't use it. Release
DR3.5 or later should be OK.
The Unix-command-line-style interface can be used by defining USE_CCOMMAND.
You'll also need to define either TWO_FILE_COMMANDLINE (to avoid stdin/stdout)
or USE_FDOPEN (to make stdin/stdout work in binary mode). See the Think C
entry for more details.
You'll also need to define TWO_FILE_COMMANDLINE to avoid stdin/stdout.
This means that when using the cjpeg/djpeg programs, you'll have to type the
input and output file names in the "Arguments" text-edit box, rather than
using the file radio buttons. (Perhaps USE_FDOPEN or USE_SETMODE would
eliminate the problem, but I haven't heard from anyone who's tried it.)
On 680x0 Macs, Metrowerks defines type "double" as a 10-byte IEEE extended
float. jmemmgr.c won't like this: it wants sizeof(ALIGN_TYPE) to be a power
of 2. Add "#define ALIGN_TYPE long" to jconfig.h to eliminate the complaint.
The supplied configuration file jconfig.mac can be used for your jconfig.h;
it includes all the recommended symbol definitions. If you have AppleScript
installed, you can run the supplied script makeproj.mac to create CodeWarrior
project files for the library and the testbed applications, then build the
library and applications. (Thanks to Dan Sears and Don Agro for this nifty
hack, which saves us from trying to maintain CodeWarrior project files as part
of the IJG distribution...)
Macintosh, Think C:
Jim Brunner has prepared a Mac-style user interface for the IJG library.
Unfortunately, the released version of it only works with pre-v5 libraries;
still, it may be a useful starting point. You can obtain Jim's additional
source code from the Info-Mac archives, at sumex-aim.stanford.edu or mirrors
thereof; see file /info-mac/dev/src/jpeg-convert-c.hqx. Jim's documentation
also includes more detailed build instructions for Think C.
The documentation in Jim Brunner's "JPEG Convert" source code (see above)
includes detailed build instructions for Think C; it's probably somewhat
out of date for the current release, but may be helpful.
If you want to build the minimal command line version, proceed as follows.
You'll have to prepare project files for the programs; we don't include any
@@ -695,6 +728,9 @@ On 680x0 Macs, Think C defines type "double" as a 12-byte IEEE extended float.
jmemmgr.c won't like this: it wants sizeof(ALIGN_TYPE) to be a power of 2.
Add "#define ALIGN_TYPE long" to jconfig.h to eliminate the complaint.
jconfig.mac should work as a jconfig.h configuration file for Think C,
but the makeproj.mac AppleScript script is specific to CodeWarrior. Sorry.
MIPS R3000:
@@ -705,7 +741,7 @@ Note that the R3000 chip is found in workstations from DEC and others.
MS-DOS, generic comments for 16-bit compilers:
The IJG code is designed to be compiled in 80x86 "small" or "medium" memory
The IJG code is designed to work well in 80x86 "small" or "medium" memory
models (i.e., data pointers are 16 bits unless explicitly declared "far";
code pointers can be either size). You may be able to use small model to
compile cjpeg or djpeg by itself, but you will probably have to use medium
@@ -721,7 +757,7 @@ The DOS-specific memory manager, jmemdos.c, should be used if possible.
It needs some assembly-code routines which are in jmemdosa.asm; make sure
your makefile assembles that file and includes it in the library. If you
don't have a suitable assembler, you can get pre-assembled object files for
jmemdosa by FTP from ftp.uu.net: graphics/jpeg/jdosaobj.zip. (DOS-oriented
jmemdosa by FTP from ftp.uu.net:/graphics/jpeg/jdosaobj.zip. (DOS-oriented
distributions of the IJG source code often include these object files.)
When using jmemdos.c, jconfig.h must define USE_MSDOS_MEMMGR and must set
@@ -778,31 +814,22 @@ jconfig.bcc already includes #define USE_SETMODE to make this work.
(fdopen does not work correctly.)
MS-DOS, DJGPP:
Use a recent version of DJGPP (1.11 or better). If you prefer two-file
command line style, change the supplied jconfig.dj to define
TWO_FILE_COMMANDLINE. makefile.dj is set up to generate only COFF files
(cjpeg, djpeg, etc) when you say make. After testing, say "make exe" to
make executables with stub.exe, or "make standalone" if you want executables
that include go32. You will probably need to tweak the makefile's pointer to
go32.exe to do "make standalone".
MS-DOS, Microsoft C:
makefile.mc6 works with Microsoft C, Visual C++, etc. Note that this
makefile assumes that the working copy of itself is called "makefile".
If you want to call it something else, say "makefile.mak", be sure to adjust
the dependency line that reads "$(RFILE) : makefile". Otherwise the make
will fail because it doesn't know how to create "makefile". Worse, some
releases of Microsoft's make utilities give an incorrect error message in
this situation.
makefile.mc6 works with Microsoft C, DOS Visual C++, etc. It should only
be used if you want to build a 16-bit (small or medium memory model) program.
If you want one-file command line style, just undefine TWO_FILE_COMMANDLINE.
jconfig.mc6 already includes #define USE_SETMODE to make this work.
(fdopen does not work correctly.)
Note that this makefile assumes that the working copy of itself is called
"makefile". If you want to call it something else, say "makefile.mak",
be sure to adjust the dependency line that reads "$(RFILE) : makefile".
Otherwise the make will fail because it doesn't know how to create "makefile".
Worse, some releases of Microsoft's make utilities give an incorrect error
message in this situation.
Old versions of MS C fail with an "out of macro expansion space" error
because they can't cope with the macro TRACEMS8 (defined in jerror.h).
If this happens to you, the easiest solution is to change TRACEMS8 to
@@ -813,11 +840,12 @@ Original MS C 6.0 is very buggy; it compiles incorrect code unless you turn
off optimization entirely (remove -O from CFLAGS). 6.00A is better, but it
still generates bad code if you enable loop optimizations (-Ol or -Ox).
MS C 8.0 reportedly fails to compile jquant1.c if optimization is turned off
(yes, off).
MS C 8.0 crashes when compiling jquant1.c with optimization switch /Oo ...
which is on by default. To work around this bug, compile that one file
with /Oo-.
Microsoft Windows (all versions):
Microsoft Windows (all versions), generic comments:
Some Windows system include files define typedef boolean as "unsigned char".
The IJG code also defines typedef boolean, but we make it "int" by default.
@@ -825,45 +853,87 @@ This doesn't affect the IJG programs because we don't import those Windows
include files. But if you use the JPEG library in your own program, and some
of your program's files import one definition of boolean while some import the
other, you can get all sorts of mysterious problems. A good preventive step
is to change jmorecfg.h to define boolean as unsigned char. We recommend
making that part of jmorecfg.h read like this:
is to make the IJG library use "unsigned char" for boolean. To do that,
add something like this to your jconfig.h file:
/* Define "boolean" as unsigned char, not int, per Windows custom */
#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */
typedef unsigned char boolean;
#endif
In v6a and later, using incompatible definitions of boolean will usually lead
to the failure message "JPEG parameter struct mismatch", rather than the
difficult-to-diagnose bugs it caused with earlier versions.
#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */
(This is already in jconfig.vc, by the way.)
windef.h contains the declarations
#define far
#define FAR far
Since jmorecfg.h tries to define FAR as empty, you may get a compiler
warning if you include both jpeglib.h and windef.h (which windows.h
includes). To suppress the warning, you can put "#ifndef FAR"/"#endif"
around the line "#define FAR" in jmorecfg.h.
(Something like this is already in jmorecfg.h, by the way.)
When using the library in a Windows application, you will almost certainly
want to modify or replace the error handler module jerror.c, since our
default error handler does a couple of inappropriate things:
1. it tries to write error and warning messages on stderr;
2. in event of a fatal error, it exits by calling exit().
A simple stopgap solution for problem 1 is to replace the line
fprintf(stderr, "%s\n", buffer);
(in output_message in jerror.c) with something like
MessageBox(GetActiveWindow(),buffer,"JPEG Error",MB_OK);
(in output_message in jerror.c) with
MessageBox(GetActiveWindow(),buffer,"JPEG Error",MB_OK|MB_ICONERROR);
It's highly recommended that you at least do that much, since otherwise
error messages will disappear into nowhere.
error messages will disappear into nowhere. (Beginning with IJG v6b, this
code is already present in jerror.c; just define USE_WINDOWS_MESSAGEBOX in
jconfig.h to enable it.)
The proper solution for problem 2 is to return control to your calling
application after a library error. This can be done with the setjmp/longjmp
technique discussed in libjpeg.doc and illustrated in example.c.
technique discussed in libjpeg.txt and illustrated in example.c. (NOTE:
some older Windows C compilers provide versions of setjmp/longjmp that
don't actually work under Windows. You may need to use the Windows system
functions Catch and Throw instead.)
The recommended memory manager under Windows is jmemnobs.c; in other words,
let Windows do any virtual memory management needed. You should NOT use
jmemdos.c nor jmemdosa.asm under Windows.
For Windows 3.1, we recommend compiling in medium or large memory model;
for newer Windows versions, use a 32-bit flat memory model. (See the MS-DOS
sections above for more info about memory models.) In the 16-bit memory
models only, you'll need to put
#define MAX_ALLOC_CHUNK 65520L /* Maximum request to malloc() */
into jconfig.h to limit allocation chunks to 64Kb. (Without that, you'd
have to use huge memory model, which slows things down unnecessarily.)
jmemnobs.c works without modification in large or flat memory models, but to
use medium model, you need to modify its jpeg_get_large and jpeg_free_large
routines to allocate far memory. In any case, you might like to replace
its calls to malloc and free with direct calls on Windows memory allocation
functions.
You may also want to modify jdatasrc.c and jdatadst.c to use Windows file
operations rather than fread/fwrite. This is only necessary if your C
compiler doesn't provide a competent implementation of C stdio functions.
You might want to tweak the RGB_xxx macros in jmorecfg.h so that the library
will accept or deliver color pixels in BGR sample order, not RGB; BGR order
is usually more convenient under Windows. Note that this change will break
the sample applications cjpeg/djpeg, but the library itself works fine.
Many people want to convert the IJG library into a DLL. This is reasonably
straightforward, but watch out for the following:
1. Don't try to compile as a DLL in small or medium memory model; use
large model, or even better, 32-bit flat model. Many places in the IJG code
assume the address of a local variable is an ordinary (not FAR) pointer;
that isn't true in a medium-model DLL.
2. Microsoft C cannot pass file pointers between applications and DLLs.
(See Microsoft Knowledge Base, PSS ID Number Q50336.) So jdatasrc.c and
jdatadst.c don't work if you open a file in your application and then pass
the pointer to the DLL. One workaround is to make jdatasrc.c/jdatadst.c
part of your main application rather than part of the DLL.
3. You'll probably need to modify the macros GLOBAL() and EXTERN() to
attach suitable linkage keywords to the exported routine names. Similarly,
you'll want to modify METHODDEF() and JMETHOD() to ensure function pointers
@@ -871,10 +941,13 @@ are declared in a way that lets application routines be called back through
the function pointers. These macros are in jmorecfg.h. Typical definitions
for a 16-bit DLL are:
#define GLOBAL(type) type _far _pascal _loadds _export
#define EXTERN(type) extern type _far _pascal
#define EXTERN(type) extern type _far _pascal _loadds
#define METHODDEF(type) static type _far _pascal
#define JMETHOD(type,methodname,arglist) \
type (_far _pascal *methodname) arglist
For a 32-bit DLL you may want something like
#define GLOBAL(type) __declspec(dllexport) type
#define EXTERN(type) extern __declspec(dllexport) type
Although not all the GLOBAL routines are actually intended to be called by
the application, the performance cost of making them all DLL entry points is
negligible.
@@ -888,6 +961,12 @@ but hasn't been very high priority --- any volunteers out there?
Microsoft Windows, Borland C:
The provided jconfig.bcc should work OK in a 32-bit Windows environment,
but you'll need to tweak it in a 16-bit environment (you'd need to define
NEED_FAR_POINTERS and MAX_ALLOC_CHUNK). Beware that makefile.bcc will need
alteration if you want to use it for Windows --- in particular, you should
use jmemnobs.c not jmemdos.c under Windows.
Borland C++ 4.5 fails with an internal compiler error when trying to compile
jdmerge.c in 32-bit mode. If enough people complain, perhaps Borland will fix
it. In the meantime, the simplest known workaround is to add a redundant
@@ -902,6 +981,92 @@ doesn't trigger the bug.
Recent reports suggest that this bug does not occur with "bcc32a" (the
Pentium-optimized version of the compiler).
Another report from a user of Borland C 4.5 was that incorrect code (leading
to a color shift in processed images) was produced if any of the following
optimization switch combinations were used:
-Ot -Og
-Ot -Op
-Ot -Om
So try backing off on optimization if you see such a problem. (Are there
several different releases all numbered "4.5"??)
Microsoft Windows, Microsoft Visual C++:
jconfig.vc should work OK with any Microsoft compiler for a 32-bit memory
model. makefile.vc is intended for command-line use. (If you are using
the Developer Studio environment, you may prefer the DevStudio project
files; see below.)
IJG JPEG 7 adds extern "C" to jpeglib.h. This avoids the need to put
extern "C" { ... } around #include "jpeglib.h" in your C++ application.
You can also force VC++ to treat the library as C++ code by renaming
all the *.c files to *.cpp (and adjusting the makefile to match).
In this case you also need to define the symbol DONT_USE_EXTERN_C in
the configuration to prevent jpeglib.h from using extern "C".
Microsoft Windows, Microsoft Visual C++ 6 Developer Studio:
We include makefiles that should work as project files in DevStudio 6.0 or
later. There is a library makefile that builds the IJG library as a static
Win32 library, and application makefiles that build the sample applications
as Win32 console applications. (Even if you only want the library, we
recommend building the applications so that you can run the self-test.)
To use:
1. Open the command prompt, change to the main directory and execute the
command line
NMAKE /f makefile.vc setup-vc6
This will move jconfig.vc to jconfig.h and makefiles to project files.
(Note that the renaming is critical!)
2. Open the workspace file jpeg.dsw, build the library project.
(If you are using DevStudio more recent than 6.0, you'll probably
get a message saying that the project files are being updated.)
3. Open the workspace file apps.dsw, build the application projects.
4. To perform the self-test, execute the command line
NMAKE /f makefile.vc test-build
5. Move the application .exe files from `app`\Release to an
appropriate location on your path.
Microsoft Windows, Microsoft Visual C++ 2010 Developer Studio (v10):
We include makefiles that should work as project files in Visual Studio
2010 or later. There is a library makefile that builds the IJG library
as a static Win32 library, and application makefiles that build the sample
applications as Win32 console applications. (Even if you only want the
library, we recommend building the applications so that you can run the
self-test.)
To use:
1. Open the command prompt, change to the main directory and execute the
command line
NMAKE /f makefile.vc setup-v10
This will move jconfig.vc to jconfig.h and makefiles to project files.
(Note that the renaming is critical!)
2. Open the solution file jpeg.sln, build the library project.
(If you are using Visual Studio more recent than 2010 (v10), you'll
probably get a message saying that the project files are being updated.)
3. Open the solution file apps.sln, build the application projects.
4. To perform the self-test, execute the command line
NMAKE /f makefile.vc test-build
5. Move the application .exe files from `app`\Release to an
appropriate location on your path.
Note:
There seems to be an optimization bug in the compiler which causes the
self-test to fail with the color quantization option.
We have disabled optimization for the file jquant2.c in the library
project file which causes the self-test to pass properly.
OS/2, Borland C++:
Watch out for optimization bugs in older Borland compilers; you may need
to back off the optimization switch settings. See the comments in
makefile.bcc.
SGI:

153
jaricom.c Normal file
View File

@@ -0,0 +1,153 @@
/*
* jaricom.c
*
* Developed 1997-2009 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains probability estimation tables for common use in
* arithmetic entropy encoding and decoding routines.
*
* This data represents Table D.2 in the JPEG spec (ISO/IEC IS 10918-1
* and CCITT Recommendation ITU-T T.81) and Table 24 in the JBIG spec
* (ISO/IEC IS 11544 and CCITT Recommendation ITU-T T.82).
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
/* The following #define specifies the packing of the four components
* into the compact INT32 representation.
* Note that this formula must match the actual arithmetic encoder
* and decoder implementation. The implementation has to be changed
* if this formula is changed.
* The current organization is leaned on Markus Kuhn's JBIG
* implementation (jbig_tab.c).
*/
#define V(i,a,b,c,d) (((INT32)a << 16) | ((INT32)c << 8) | ((INT32)d << 7) | b)
const INT32 jpeg_aritab[113+1] = {
/*
* Index, Qe_Value, Next_Index_LPS, Next_Index_MPS, Switch_MPS
*/
V( 0, 0x5a1d, 1, 1, 1 ),
V( 1, 0x2586, 14, 2, 0 ),
V( 2, 0x1114, 16, 3, 0 ),
V( 3, 0x080b, 18, 4, 0 ),
V( 4, 0x03d8, 20, 5, 0 ),
V( 5, 0x01da, 23, 6, 0 ),
V( 6, 0x00e5, 25, 7, 0 ),
V( 7, 0x006f, 28, 8, 0 ),
V( 8, 0x0036, 30, 9, 0 ),
V( 9, 0x001a, 33, 10, 0 ),
V( 10, 0x000d, 35, 11, 0 ),
V( 11, 0x0006, 9, 12, 0 ),
V( 12, 0x0003, 10, 13, 0 ),
V( 13, 0x0001, 12, 13, 0 ),
V( 14, 0x5a7f, 15, 15, 1 ),
V( 15, 0x3f25, 36, 16, 0 ),
V( 16, 0x2cf2, 38, 17, 0 ),
V( 17, 0x207c, 39, 18, 0 ),
V( 18, 0x17b9, 40, 19, 0 ),
V( 19, 0x1182, 42, 20, 0 ),
V( 20, 0x0cef, 43, 21, 0 ),
V( 21, 0x09a1, 45, 22, 0 ),
V( 22, 0x072f, 46, 23, 0 ),
V( 23, 0x055c, 48, 24, 0 ),
V( 24, 0x0406, 49, 25, 0 ),
V( 25, 0x0303, 51, 26, 0 ),
V( 26, 0x0240, 52, 27, 0 ),
V( 27, 0x01b1, 54, 28, 0 ),
V( 28, 0x0144, 56, 29, 0 ),
V( 29, 0x00f5, 57, 30, 0 ),
V( 30, 0x00b7, 59, 31, 0 ),
V( 31, 0x008a, 60, 32, 0 ),
V( 32, 0x0068, 62, 33, 0 ),
V( 33, 0x004e, 63, 34, 0 ),
V( 34, 0x003b, 32, 35, 0 ),
V( 35, 0x002c, 33, 9, 0 ),
V( 36, 0x5ae1, 37, 37, 1 ),
V( 37, 0x484c, 64, 38, 0 ),
V( 38, 0x3a0d, 65, 39, 0 ),
V( 39, 0x2ef1, 67, 40, 0 ),
V( 40, 0x261f, 68, 41, 0 ),
V( 41, 0x1f33, 69, 42, 0 ),
V( 42, 0x19a8, 70, 43, 0 ),
V( 43, 0x1518, 72, 44, 0 ),
V( 44, 0x1177, 73, 45, 0 ),
V( 45, 0x0e74, 74, 46, 0 ),
V( 46, 0x0bfb, 75, 47, 0 ),
V( 47, 0x09f8, 77, 48, 0 ),
V( 48, 0x0861, 78, 49, 0 ),
V( 49, 0x0706, 79, 50, 0 ),
V( 50, 0x05cd, 48, 51, 0 ),
V( 51, 0x04de, 50, 52, 0 ),
V( 52, 0x040f, 50, 53, 0 ),
V( 53, 0x0363, 51, 54, 0 ),
V( 54, 0x02d4, 52, 55, 0 ),
V( 55, 0x025c, 53, 56, 0 ),
V( 56, 0x01f8, 54, 57, 0 ),
V( 57, 0x01a4, 55, 58, 0 ),
V( 58, 0x0160, 56, 59, 0 ),
V( 59, 0x0125, 57, 60, 0 ),
V( 60, 0x00f6, 58, 61, 0 ),
V( 61, 0x00cb, 59, 62, 0 ),
V( 62, 0x00ab, 61, 63, 0 ),
V( 63, 0x008f, 61, 32, 0 ),
V( 64, 0x5b12, 65, 65, 1 ),
V( 65, 0x4d04, 80, 66, 0 ),
V( 66, 0x412c, 81, 67, 0 ),
V( 67, 0x37d8, 82, 68, 0 ),
V( 68, 0x2fe8, 83, 69, 0 ),
V( 69, 0x293c, 84, 70, 0 ),
V( 70, 0x2379, 86, 71, 0 ),
V( 71, 0x1edf, 87, 72, 0 ),
V( 72, 0x1aa9, 87, 73, 0 ),
V( 73, 0x174e, 72, 74, 0 ),
V( 74, 0x1424, 72, 75, 0 ),
V( 75, 0x119c, 74, 76, 0 ),
V( 76, 0x0f6b, 74, 77, 0 ),
V( 77, 0x0d51, 75, 78, 0 ),
V( 78, 0x0bb6, 77, 79, 0 ),
V( 79, 0x0a40, 77, 48, 0 ),
V( 80, 0x5832, 80, 81, 1 ),
V( 81, 0x4d1c, 88, 82, 0 ),
V( 82, 0x438e, 89, 83, 0 ),
V( 83, 0x3bdd, 90, 84, 0 ),
V( 84, 0x34ee, 91, 85, 0 ),
V( 85, 0x2eae, 92, 86, 0 ),
V( 86, 0x299a, 93, 87, 0 ),
V( 87, 0x2516, 86, 71, 0 ),
V( 88, 0x5570, 88, 89, 1 ),
V( 89, 0x4ca9, 95, 90, 0 ),
V( 90, 0x44d9, 96, 91, 0 ),
V( 91, 0x3e22, 97, 92, 0 ),
V( 92, 0x3824, 99, 93, 0 ),
V( 93, 0x32b4, 99, 94, 0 ),
V( 94, 0x2e17, 93, 86, 0 ),
V( 95, 0x56a8, 95, 96, 1 ),
V( 96, 0x4f46, 101, 97, 0 ),
V( 97, 0x47e5, 102, 98, 0 ),
V( 98, 0x41cf, 103, 99, 0 ),
V( 99, 0x3c3d, 104, 100, 0 ),
V( 100, 0x375e, 99, 93, 0 ),
V( 101, 0x5231, 105, 102, 0 ),
V( 102, 0x4c0f, 106, 103, 0 ),
V( 103, 0x4639, 107, 104, 0 ),
V( 104, 0x415e, 103, 99, 0 ),
V( 105, 0x5627, 105, 106, 1 ),
V( 106, 0x50e7, 108, 107, 0 ),
V( 107, 0x4b85, 109, 103, 0 ),
V( 108, 0x5597, 110, 109, 0 ),
V( 109, 0x504f, 111, 107, 0 ),
V( 110, 0x5a10, 110, 111, 1 ),
V( 111, 0x5522, 112, 109, 0 ),
V( 112, 0x59eb, 112, 111, 1 ),
/*
* This last entry is used for fixed probability estimate of 0.5
* as recommended in Section 10.3 Table 5 of ITU-T Rec. T.851.
*/
V( 113, 0x5a1d, 113, 113, 0 )
};

View File

@@ -1,7 +1,8 @@
/*
* jcapimin.c
*
* Copyright (C) 1994-1996, Thomas G. Lane.
* Copyright (C) 1994-1998, Thomas G. Lane.
* Modified 2003-2010 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -39,13 +40,18 @@ jpeg_CreateCompress (j_compress_ptr cinfo, int version, size_t structsize)
ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE,
(int) SIZEOF(struct jpeg_compress_struct), (int) structsize);
/* For debugging purposes, zero the whole master structure.
* But error manager pointer is already there, so save and restore it.
/* For debugging purposes, we zero the whole master structure.
* But the application has already set the err pointer, and may have set
* client_data, so we have to save and restore those fields.
* Note: if application hasn't set client_data, tools like Purify may
* complain here.
*/
{
struct jpeg_error_mgr * err = cinfo->err;
void * client_data = cinfo->client_data; /* ignore Purify complaint here */
MEMZERO(cinfo, SIZEOF(struct jpeg_compress_struct));
cinfo->err = err;
cinfo->client_data = client_data;
}
cinfo->is_decompressor = FALSE;
@@ -58,14 +64,27 @@ jpeg_CreateCompress (j_compress_ptr cinfo, int version, size_t structsize)
cinfo->comp_info = NULL;
for (i = 0; i < NUM_QUANT_TBLS; i++)
for (i = 0; i < NUM_QUANT_TBLS; i++) {
cinfo->quant_tbl_ptrs[i] = NULL;
#if JPEG_LIB_VERSION >= 70
cinfo->q_scale_factor[i] = 100;
#endif
}
for (i = 0; i < NUM_HUFF_TBLS; i++) {
cinfo->dc_huff_tbl_ptrs[i] = NULL;
cinfo->ac_huff_tbl_ptrs[i] = NULL;
}
#if JPEG_LIB_VERSION >= 80
/* Must do it here for emit_dqt in case jpeg_write_tables is used */
cinfo->block_size = DCTSIZE;
cinfo->natural_order = jpeg_natural_order;
cinfo->lim_Se = DCTSIZE2-1;
#endif
cinfo->script_space = NULL;
cinfo->input_gamma = 1.0; /* in case application forgets */
/* OK, I'm ready */
@@ -185,13 +204,40 @@ GLOBAL(void)
jpeg_write_marker (j_compress_ptr cinfo, int marker,
const JOCTET *dataptr, unsigned int datalen)
{
JMETHOD(void, write_marker_byte, (j_compress_ptr info, int val));
if (cinfo->next_scanline != 0 ||
(cinfo->global_state != CSTATE_SCANNING &&
cinfo->global_state != CSTATE_RAW_OK &&
cinfo->global_state != CSTATE_WRCOEFS))
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
(*cinfo->marker->write_any_marker) (cinfo, marker, dataptr, datalen);
(*cinfo->marker->write_marker_header) (cinfo, marker, datalen);
write_marker_byte = cinfo->marker->write_marker_byte; /* copy for speed */
while (datalen--) {
(*write_marker_byte) (cinfo, *dataptr);
dataptr++;
}
}
/* Same, but piecemeal. */
GLOBAL(void)
jpeg_write_m_header (j_compress_ptr cinfo, int marker, unsigned int datalen)
{
if (cinfo->next_scanline != 0 ||
(cinfo->global_state != CSTATE_SCANNING &&
cinfo->global_state != CSTATE_RAW_OK &&
cinfo->global_state != CSTATE_WRCOEFS))
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
(*cinfo->marker->write_marker_header) (cinfo, marker, datalen);
}
GLOBAL(void)
jpeg_write_m_byte (j_compress_ptr cinfo, int val)
{
(*cinfo->marker->write_marker_byte) (cinfo, val);
}
@@ -231,6 +277,16 @@ jpeg_write_tables (j_compress_ptr cinfo)
(*cinfo->marker->write_tables_only) (cinfo);
/* And clean up. */
(*cinfo->dest->term_destination) (cinfo);
/* We can use jpeg_abort to release memory. */
jpeg_abort((j_common_ptr) cinfo);
/*
* In library releases up through v6a, we called jpeg_abort() here to free
* any working memory allocated by the destination manager and marker
* writer. Some applications had a problem with that: they allocated space
* of their own from the library memory manager, and didn't want it to go
* away during write_tables. So now we do nothing. This will cause a
* memory leak if an app calls write_tables repeatedly without doing a full
* compression cycle or otherwise resetting the JPEG object. However, that
* seems less bad than unexpectedly freeing memory in the normal case.
* An app that prefers the old behavior can call jpeg_abort for itself after
* each call to jpeg_write_tables().
*/
}

925
jcarith.c Normal file
View File

@@ -0,0 +1,925 @@
/*
* jcarith.c
*
* Developed 1997-2009 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains portable arithmetic entropy encoding routines for JPEG
* (implementing the ISO/IEC IS 10918-1 and CCITT Recommendation ITU-T T.81).
*
* Both sequential and progressive modes are supported in this single module.
*
* Suspension is not currently supported in this module.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
/* Expanded entropy encoder object for arithmetic encoding. */
typedef struct {
struct jpeg_entropy_encoder pub; /* public fields */
INT32 c; /* C register, base of coding interval, layout as in sec. D.1.3 */
INT32 a; /* A register, normalized size of coding interval */
INT32 sc; /* counter for stacked 0xFF values which might overflow */
INT32 zc; /* counter for pending 0x00 output values which might *
* be discarded at the end ("Pacman" termination) */
int ct; /* bit shift counter, determines when next byte will be written */
int buffer; /* buffer for most recent output byte != 0xFF */
int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
int dc_context[MAX_COMPS_IN_SCAN]; /* context index for DC conditioning */
unsigned int restarts_to_go; /* MCUs left in this restart interval */
int next_restart_num; /* next restart number to write (0-7) */
/* Pointers to statistics areas (these workspaces have image lifespan) */
unsigned char * dc_stats[NUM_ARITH_TBLS];
unsigned char * ac_stats[NUM_ARITH_TBLS];
/* Statistics bin for coding with fixed probability 0.5 */
unsigned char fixed_bin[4];
} arith_entropy_encoder;
typedef arith_entropy_encoder * arith_entropy_ptr;
/* The following two definitions specify the allocation chunk size
* for the statistics area.
* According to sections F.1.4.4.1.3 and F.1.4.4.2, we need at least
* 49 statistics bins for DC, and 245 statistics bins for AC coding.
*
* We use a compact representation with 1 byte per statistics bin,
* thus the numbers directly represent byte sizes.
* This 1 byte per statistics bin contains the meaning of the MPS
* (more probable symbol) in the highest bit (mask 0x80), and the
* index into the probability estimation state machine table
* in the lower bits (mask 0x7F).
*/
#define DC_STAT_BINS 64
#define AC_STAT_BINS 256
/* NOTE: Uncomment the following #define if you want to use the
* given formula for calculating the AC conditioning parameter Kx
* for spectral selection progressive coding in section G.1.3.2
* of the spec (Kx = Kmin + SRL (8 + Se - Kmin) 4).
* Although the spec and P&M authors claim that this "has proven
* to give good results for 8 bit precision samples", I'm not
* convinced yet that this is really beneficial.
* Early tests gave only very marginal compression enhancements
* (a few - around 5 or so - bytes even for very large files),
* which would turn out rather negative if we'd suppress the
* DAC (Define Arithmetic Conditioning) marker segments for
* the default parameters in the future.
* Note that currently the marker writing module emits 12-byte
* DAC segments for a full-component scan in a color image.
* This is not worth worrying about IMHO. However, since the
* spec defines the default values to be used if the tables
* are omitted (unlike Huffman tables, which are required
* anyway), one might optimize this behaviour in the future,
* and then it would be disadvantageous to use custom tables if
* they don't provide sufficient gain to exceed the DAC size.
*
* On the other hand, I'd consider it as a reasonable result
* that the conditioning has no significant influence on the
* compression performance. This means that the basic
* statistical model is already rather stable.
*
* Thus, at the moment, we use the default conditioning values
* anyway, and do not use the custom formula.
*
#define CALCULATE_SPECTRAL_CONDITIONING
*/
/* IRIGHT_SHIFT is like RIGHT_SHIFT, but works on int rather than INT32.
* We assume that int right shift is unsigned if INT32 right shift is,
* which should be safe.
*/
#ifdef RIGHT_SHIFT_IS_UNSIGNED
#define ISHIFT_TEMPS int ishift_temp;
#define IRIGHT_SHIFT(x,shft) \
((ishift_temp = (x)) < 0 ? \
(ishift_temp >> (shft)) | ((~0) << (16-(shft))) : \
(ishift_temp >> (shft)))
#else
#define ISHIFT_TEMPS
#define IRIGHT_SHIFT(x,shft) ((x) >> (shft))
#endif
LOCAL(void)
emit_byte (int val, j_compress_ptr cinfo)
/* Write next output byte; we do not support suspension in this module. */
{
struct jpeg_destination_mgr * dest = cinfo->dest;
*dest->next_output_byte++ = (JOCTET) val;
if (--dest->free_in_buffer == 0)
if (! (*dest->empty_output_buffer) (cinfo))
ERREXIT(cinfo, JERR_CANT_SUSPEND);
}
/*
* Finish up at the end of an arithmetic-compressed scan.
*/
METHODDEF(void)
finish_pass (j_compress_ptr cinfo)
{
arith_entropy_ptr e = (arith_entropy_ptr) cinfo->entropy;
INT32 temp;
/* Section D.1.8: Termination of encoding */
/* Find the e->c in the coding interval with the largest
* number of trailing zero bits */
if ((temp = (e->a - 1 + e->c) & 0xFFFF0000L) < e->c)
e->c = temp + 0x8000L;
else
e->c = temp;
/* Send remaining bytes to output */
e->c <<= e->ct;
if (e->c & 0xF8000000L) {
/* One final overflow has to be handled */
if (e->buffer >= 0) {
if (e->zc)
do emit_byte(0x00, cinfo);
while (--e->zc);
emit_byte(e->buffer + 1, cinfo);
if (e->buffer + 1 == 0xFF)
emit_byte(0x00, cinfo);
}
e->zc += e->sc; /* carry-over converts stacked 0xFF bytes to 0x00 */
e->sc = 0;
} else {
if (e->buffer == 0)
++e->zc;
else if (e->buffer >= 0) {
if (e->zc)
do emit_byte(0x00, cinfo);
while (--e->zc);
emit_byte(e->buffer, cinfo);
}
if (e->sc) {
if (e->zc)
do emit_byte(0x00, cinfo);
while (--e->zc);
do {
emit_byte(0xFF, cinfo);
emit_byte(0x00, cinfo);
} while (--e->sc);
}
}
/* Output final bytes only if they are not 0x00 */
if (e->c & 0x7FFF800L) {
if (e->zc) /* output final pending zero bytes */
do emit_byte(0x00, cinfo);
while (--e->zc);
emit_byte((e->c >> 19) & 0xFF, cinfo);
if (((e->c >> 19) & 0xFF) == 0xFF)
emit_byte(0x00, cinfo);
if (e->c & 0x7F800L) {
emit_byte((e->c >> 11) & 0xFF, cinfo);
if (((e->c >> 11) & 0xFF) == 0xFF)
emit_byte(0x00, cinfo);
}
}
}
/*
* The core arithmetic encoding routine (common in JPEG and JBIG).
* This needs to go as fast as possible.
* Machine-dependent optimization facilities
* are not utilized in this portable implementation.
* However, this code should be fairly efficient and
* may be a good base for further optimizations anyway.
*
* Parameter 'val' to be encoded may be 0 or 1 (binary decision).
*
* Note: I've added full "Pacman" termination support to the
* byte output routines, which is equivalent to the optional
* Discard_final_zeros procedure (Figure D.15) in the spec.
* Thus, we always produce the shortest possible output
* stream compliant to the spec (no trailing zero bytes,
* except for FF stuffing).
*
* I've also introduced a new scheme for accessing
* the probability estimation state machine table,
* derived from Markus Kuhn's JBIG implementation.
*/
LOCAL(void)
arith_encode (j_compress_ptr cinfo, unsigned char *st, int val)
{
register arith_entropy_ptr e = (arith_entropy_ptr) cinfo->entropy;
register unsigned char nl, nm;
register INT32 qe, temp;
register int sv;
/* Fetch values from our compact representation of Table D.2:
* Qe values and probability estimation state machine
*/
sv = *st;
qe = jpeg_aritab[sv & 0x7F]; /* => Qe_Value */
nl = qe & 0xFF; qe >>= 8; /* Next_Index_LPS + Switch_MPS */
nm = qe & 0xFF; qe >>= 8; /* Next_Index_MPS */
/* Encode & estimation procedures per sections D.1.4 & D.1.5 */
e->a -= qe;
if (val != (sv >> 7)) {
/* Encode the less probable symbol */
if (e->a >= qe) {
/* If the interval size (qe) for the less probable symbol (LPS)
* is larger than the interval size for the MPS, then exchange
* the two symbols for coding efficiency, otherwise code the LPS
* as usual: */
e->c += e->a;
e->a = qe;
}
*st = (sv & 0x80) ^ nl; /* Estimate_after_LPS */
} else {
/* Encode the more probable symbol */
if (e->a >= 0x8000L)
return; /* A >= 0x8000 -> ready, no renormalization required */
if (e->a < qe) {
/* If the interval size (qe) for the less probable symbol (LPS)
* is larger than the interval size for the MPS, then exchange
* the two symbols for coding efficiency: */
e->c += e->a;
e->a = qe;
}
*st = (sv & 0x80) ^ nm; /* Estimate_after_MPS */
}
/* Renormalization & data output per section D.1.6 */
do {
e->a <<= 1;
e->c <<= 1;
if (--e->ct == 0) {
/* Another byte is ready for output */
temp = e->c >> 19;
if (temp > 0xFF) {
/* Handle overflow over all stacked 0xFF bytes */
if (e->buffer >= 0) {
if (e->zc)
do emit_byte(0x00, cinfo);
while (--e->zc);
emit_byte(e->buffer + 1, cinfo);
if (e->buffer + 1 == 0xFF)
emit_byte(0x00, cinfo);
}
e->zc += e->sc; /* carry-over converts stacked 0xFF bytes to 0x00 */
e->sc = 0;
/* Note: The 3 spacer bits in the C register guarantee
* that the new buffer byte can't be 0xFF here
* (see page 160 in the P&M JPEG book). */
e->buffer = temp & 0xFF; /* new output byte, might overflow later */
} else if (temp == 0xFF) {
++e->sc; /* stack 0xFF byte (which might overflow later) */
} else {
/* Output all stacked 0xFF bytes, they will not overflow any more */
if (e->buffer == 0)
++e->zc;
else if (e->buffer >= 0) {
if (e->zc)
do emit_byte(0x00, cinfo);
while (--e->zc);
emit_byte(e->buffer, cinfo);
}
if (e->sc) {
if (e->zc)
do emit_byte(0x00, cinfo);
while (--e->zc);
do {
emit_byte(0xFF, cinfo);
emit_byte(0x00, cinfo);
} while (--e->sc);
}
e->buffer = temp & 0xFF; /* new output byte (can still overflow) */
}
e->c &= 0x7FFFFL;
e->ct += 8;
}
} while (e->a < 0x8000L);
}
/*
* Emit a restart marker & resynchronize predictions.
*/
LOCAL(void)
emit_restart (j_compress_ptr cinfo, int restart_num)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
int ci;
jpeg_component_info * compptr;
finish_pass(cinfo);
emit_byte(0xFF, cinfo);
emit_byte(JPEG_RST0 + restart_num, cinfo);
/* Re-initialize statistics areas */
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
/* DC needs no table for refinement scan */
if (cinfo->progressive_mode == 0 || (cinfo->Ss == 0 && cinfo->Ah == 0)) {
MEMZERO(entropy->dc_stats[compptr->dc_tbl_no], DC_STAT_BINS);
/* Reset DC predictions to 0 */
entropy->last_dc_val[ci] = 0;
entropy->dc_context[ci] = 0;
}
/* AC needs no table when not present */
if (cinfo->progressive_mode == 0 || cinfo->Se) {
MEMZERO(entropy->ac_stats[compptr->ac_tbl_no], AC_STAT_BINS);
}
}
/* Reset arithmetic encoding variables */
entropy->c = 0;
entropy->a = 0x10000L;
entropy->sc = 0;
entropy->zc = 0;
entropy->ct = 11;
entropy->buffer = -1; /* empty */
}
/*
* MCU encoding for DC initial scan (either spectral selection,
* or first pass of successive approximation).
*/
METHODDEF(boolean)
encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
JBLOCKROW block;
unsigned char *st;
int blkn, ci, tbl;
int v, v2, m;
ISHIFT_TEMPS
/* Emit restart marker if needed */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0) {
emit_restart(cinfo, entropy->next_restart_num);
entropy->restarts_to_go = cinfo->restart_interval;
entropy->next_restart_num++;
entropy->next_restart_num &= 7;
}
entropy->restarts_to_go--;
}
/* Encode the MCU data blocks */
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
block = MCU_data[blkn];
ci = cinfo->MCU_membership[blkn];
tbl = cinfo->cur_comp_info[ci]->dc_tbl_no;
/* Compute the DC value after the required point transform by Al.
* This is simply an arithmetic right shift.
*/
m = IRIGHT_SHIFT((int) ((*block)[0]), cinfo->Al);
/* Sections F.1.4.1 & F.1.4.4.1: Encoding of DC coefficients */
/* Table F.4: Point to statistics bin S0 for DC coefficient coding */
st = entropy->dc_stats[tbl] + entropy->dc_context[ci];
/* Figure F.4: Encode_DC_DIFF */
if ((v = m - entropy->last_dc_val[ci]) == 0) {
arith_encode(cinfo, st, 0);
entropy->dc_context[ci] = 0; /* zero diff category */
} else {
entropy->last_dc_val[ci] = m;
arith_encode(cinfo, st, 1);
/* Figure F.6: Encoding nonzero value v */
/* Figure F.7: Encoding the sign of v */
if (v > 0) {
arith_encode(cinfo, st + 1, 0); /* Table F.4: SS = S0 + 1 */
st += 2; /* Table F.4: SP = S0 + 2 */
entropy->dc_context[ci] = 4; /* small positive diff category */
} else {
v = -v;
arith_encode(cinfo, st + 1, 1); /* Table F.4: SS = S0 + 1 */
st += 3; /* Table F.4: SN = S0 + 3 */
entropy->dc_context[ci] = 8; /* small negative diff category */
}
/* Figure F.8: Encoding the magnitude category of v */
m = 0;
if (v -= 1) {
arith_encode(cinfo, st, 1);
m = 1;
v2 = v;
st = entropy->dc_stats[tbl] + 20; /* Table F.4: X1 = 20 */
while (v2 >>= 1) {
arith_encode(cinfo, st, 1);
m <<= 1;
st += 1;
}
}
arith_encode(cinfo, st, 0);
/* Section F.1.4.4.1.2: Establish dc_context conditioning category */
if (m < (int) ((1L << cinfo->arith_dc_L[tbl]) >> 1))
entropy->dc_context[ci] = 0; /* zero diff category */
else if (m > (int) ((1L << cinfo->arith_dc_U[tbl]) >> 1))
entropy->dc_context[ci] += 8; /* large diff category */
/* Figure F.9: Encoding the magnitude bit pattern of v */
st += 14;
while (m >>= 1)
arith_encode(cinfo, st, (m & v) ? 1 : 0);
}
}
return TRUE;
}
/*
* MCU encoding for AC initial scan (either spectral selection,
* or first pass of successive approximation).
*/
METHODDEF(boolean)
encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
JBLOCKROW block;
unsigned char *st;
int tbl, k, ke;
int v, v2, m;
/* Emit restart marker if needed */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0) {
emit_restart(cinfo, entropy->next_restart_num);
entropy->restarts_to_go = cinfo->restart_interval;
entropy->next_restart_num++;
entropy->next_restart_num &= 7;
}
entropy->restarts_to_go--;
}
/* Encode the MCU data block */
block = MCU_data[0];
tbl = cinfo->cur_comp_info[0]->ac_tbl_no;
/* Sections F.1.4.2 & F.1.4.4.2: Encoding of AC coefficients */
/* Establish EOB (end-of-block) index */
for (ke = cinfo->Se; ke > 0; ke--)
/* 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.
*/
if ((v = (*block)[jpeg_natural_order[ke]]) >= 0) {
if (v >>= cinfo->Al) break;
} else {
v = -v;
if (v >>= cinfo->Al) break;
}
/* Figure F.5: Encode_AC_Coefficients */
for (k = cinfo->Ss; k <= ke; k++) {
st = entropy->ac_stats[tbl] + 3 * (k - 1);
arith_encode(cinfo, st, 0); /* EOB decision */
for (;;) {
if ((v = (*block)[jpeg_natural_order[k]]) >= 0) {
if (v >>= cinfo->Al) {
arith_encode(cinfo, st + 1, 1);
arith_encode(cinfo, entropy->fixed_bin, 0);
break;
}
} else {
v = -v;
if (v >>= cinfo->Al) {
arith_encode(cinfo, st + 1, 1);
arith_encode(cinfo, entropy->fixed_bin, 1);
break;
}
}
arith_encode(cinfo, st + 1, 0); st += 3; k++;
}
st += 2;
/* Figure F.8: Encoding the magnitude category of v */
m = 0;
if (v -= 1) {
arith_encode(cinfo, st, 1);
m = 1;
v2 = v;
if (v2 >>= 1) {
arith_encode(cinfo, st, 1);
m <<= 1;
st = entropy->ac_stats[tbl] +
(k <= cinfo->arith_ac_K[tbl] ? 189 : 217);
while (v2 >>= 1) {
arith_encode(cinfo, st, 1);
m <<= 1;
st += 1;
}
}
}
arith_encode(cinfo, st, 0);
/* Figure F.9: Encoding the magnitude bit pattern of v */
st += 14;
while (m >>= 1)
arith_encode(cinfo, st, (m & v) ? 1 : 0);
}
/* Encode EOB decision only if k <= cinfo->Se */
if (k <= cinfo->Se) {
st = entropy->ac_stats[tbl] + 3 * (k - 1);
arith_encode(cinfo, st, 1);
}
return TRUE;
}
/*
* MCU encoding for DC successive approximation refinement scan.
*/
METHODDEF(boolean)
encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
unsigned char *st;
int Al, blkn;
/* Emit restart marker if needed */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0) {
emit_restart(cinfo, entropy->next_restart_num);
entropy->restarts_to_go = cinfo->restart_interval;
entropy->next_restart_num++;
entropy->next_restart_num &= 7;
}
entropy->restarts_to_go--;
}
st = entropy->fixed_bin; /* use fixed probability estimation */
Al = cinfo->Al;
/* Encode the MCU data blocks */
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
/* We simply emit the Al'th bit of the DC coefficient value. */
arith_encode(cinfo, st, (MCU_data[blkn][0][0] >> Al) & 1);
}
return TRUE;
}
/*
* MCU encoding for AC successive approximation refinement scan.
*/
METHODDEF(boolean)
encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
JBLOCKROW block;
unsigned char *st;
int tbl, k, ke, kex;
int v;
/* Emit restart marker if needed */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0) {
emit_restart(cinfo, entropy->next_restart_num);
entropy->restarts_to_go = cinfo->restart_interval;
entropy->next_restart_num++;
entropy->next_restart_num &= 7;
}
entropy->restarts_to_go--;
}
/* Encode the MCU data block */
block = MCU_data[0];
tbl = cinfo->cur_comp_info[0]->ac_tbl_no;
/* Section G.1.3.3: Encoding of AC coefficients */
/* Establish EOB (end-of-block) index */
for (ke = cinfo->Se; ke > 0; ke--)
/* 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.
*/
if ((v = (*block)[jpeg_natural_order[ke]]) >= 0) {
if (v >>= cinfo->Al) break;
} else {
v = -v;
if (v >>= cinfo->Al) break;
}
/* Establish EOBx (previous stage end-of-block) index */
for (kex = ke; kex > 0; kex--)
if ((v = (*block)[jpeg_natural_order[kex]]) >= 0) {
if (v >>= cinfo->Ah) break;
} else {
v = -v;
if (v >>= cinfo->Ah) break;
}
/* Figure G.10: Encode_AC_Coefficients_SA */
for (k = cinfo->Ss; k <= ke; k++) {
st = entropy->ac_stats[tbl] + 3 * (k - 1);
if (k > kex)
arith_encode(cinfo, st, 0); /* EOB decision */
for (;;) {
if ((v = (*block)[jpeg_natural_order[k]]) >= 0) {
if (v >>= cinfo->Al) {
if (v >> 1) /* previously nonzero coef */
arith_encode(cinfo, st + 2, (v & 1));
else { /* newly nonzero coef */
arith_encode(cinfo, st + 1, 1);
arith_encode(cinfo, entropy->fixed_bin, 0);
}
break;
}
} else {
v = -v;
if (v >>= cinfo->Al) {
if (v >> 1) /* previously nonzero coef */
arith_encode(cinfo, st + 2, (v & 1));
else { /* newly nonzero coef */
arith_encode(cinfo, st + 1, 1);
arith_encode(cinfo, entropy->fixed_bin, 1);
}
break;
}
}
arith_encode(cinfo, st + 1, 0); st += 3; k++;
}
}
/* Encode EOB decision only if k <= cinfo->Se */
if (k <= cinfo->Se) {
st = entropy->ac_stats[tbl] + 3 * (k - 1);
arith_encode(cinfo, st, 1);
}
return TRUE;
}
/*
* Encode and output one MCU's worth of arithmetic-compressed coefficients.
*/
METHODDEF(boolean)
encode_mcu (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
jpeg_component_info * compptr;
JBLOCKROW block;
unsigned char *st;
int blkn, ci, tbl, k, ke;
int v, v2, m;
/* Emit restart marker if needed */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0) {
emit_restart(cinfo, entropy->next_restart_num);
entropy->restarts_to_go = cinfo->restart_interval;
entropy->next_restart_num++;
entropy->next_restart_num &= 7;
}
entropy->restarts_to_go--;
}
/* Encode the MCU data blocks */
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
block = MCU_data[blkn];
ci = cinfo->MCU_membership[blkn];
compptr = cinfo->cur_comp_info[ci];
/* Sections F.1.4.1 & F.1.4.4.1: Encoding of DC coefficients */
tbl = compptr->dc_tbl_no;
/* Table F.4: Point to statistics bin S0 for DC coefficient coding */
st = entropy->dc_stats[tbl] + entropy->dc_context[ci];
/* Figure F.4: Encode_DC_DIFF */
if ((v = (*block)[0] - entropy->last_dc_val[ci]) == 0) {
arith_encode(cinfo, st, 0);
entropy->dc_context[ci] = 0; /* zero diff category */
} else {
entropy->last_dc_val[ci] = (*block)[0];
arith_encode(cinfo, st, 1);
/* Figure F.6: Encoding nonzero value v */
/* Figure F.7: Encoding the sign of v */
if (v > 0) {
arith_encode(cinfo, st + 1, 0); /* Table F.4: SS = S0 + 1 */
st += 2; /* Table F.4: SP = S0 + 2 */
entropy->dc_context[ci] = 4; /* small positive diff category */
} else {
v = -v;
arith_encode(cinfo, st + 1, 1); /* Table F.4: SS = S0 + 1 */
st += 3; /* Table F.4: SN = S0 + 3 */
entropy->dc_context[ci] = 8; /* small negative diff category */
}
/* Figure F.8: Encoding the magnitude category of v */
m = 0;
if (v -= 1) {
arith_encode(cinfo, st, 1);
m = 1;
v2 = v;
st = entropy->dc_stats[tbl] + 20; /* Table F.4: X1 = 20 */
while (v2 >>= 1) {
arith_encode(cinfo, st, 1);
m <<= 1;
st += 1;
}
}
arith_encode(cinfo, st, 0);
/* Section F.1.4.4.1.2: Establish dc_context conditioning category */
if (m < (int) ((1L << cinfo->arith_dc_L[tbl]) >> 1))
entropy->dc_context[ci] = 0; /* zero diff category */
else if (m > (int) ((1L << cinfo->arith_dc_U[tbl]) >> 1))
entropy->dc_context[ci] += 8; /* large diff category */
/* Figure F.9: Encoding the magnitude bit pattern of v */
st += 14;
while (m >>= 1)
arith_encode(cinfo, st, (m & v) ? 1 : 0);
}
/* Sections F.1.4.2 & F.1.4.4.2: Encoding of AC coefficients */
tbl = compptr->ac_tbl_no;
/* Establish EOB (end-of-block) index */
for (ke = DCTSIZE2 - 1; ke > 0; ke--)
if ((*block)[jpeg_natural_order[ke]]) break;
/* Figure F.5: Encode_AC_Coefficients */
for (k = 1; k <= ke; k++) {
st = entropy->ac_stats[tbl] + 3 * (k - 1);
arith_encode(cinfo, st, 0); /* EOB decision */
while ((v = (*block)[jpeg_natural_order[k]]) == 0) {
arith_encode(cinfo, st + 1, 0); st += 3; k++;
}
arith_encode(cinfo, st + 1, 1);
/* Figure F.6: Encoding nonzero value v */
/* Figure F.7: Encoding the sign of v */
if (v > 0) {
arith_encode(cinfo, entropy->fixed_bin, 0);
} else {
v = -v;
arith_encode(cinfo, entropy->fixed_bin, 1);
}
st += 2;
/* Figure F.8: Encoding the magnitude category of v */
m = 0;
if (v -= 1) {
arith_encode(cinfo, st, 1);
m = 1;
v2 = v;
if (v2 >>= 1) {
arith_encode(cinfo, st, 1);
m <<= 1;
st = entropy->ac_stats[tbl] +
(k <= cinfo->arith_ac_K[tbl] ? 189 : 217);
while (v2 >>= 1) {
arith_encode(cinfo, st, 1);
m <<= 1;
st += 1;
}
}
}
arith_encode(cinfo, st, 0);
/* Figure F.9: Encoding the magnitude bit pattern of v */
st += 14;
while (m >>= 1)
arith_encode(cinfo, st, (m & v) ? 1 : 0);
}
/* Encode EOB decision only if k <= DCTSIZE2 - 1 */
if (k <= DCTSIZE2 - 1) {
st = entropy->ac_stats[tbl] + 3 * (k - 1);
arith_encode(cinfo, st, 1);
}
}
return TRUE;
}
/*
* Initialize for an arithmetic-compressed scan.
*/
METHODDEF(void)
start_pass (j_compress_ptr cinfo, boolean gather_statistics)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
int ci, tbl;
jpeg_component_info * compptr;
if (gather_statistics)
/* Make sure to avoid that in the master control logic!
* We are fully adaptive here and need no extra
* statistics gathering pass!
*/
ERREXIT(cinfo, JERR_NOT_COMPILED);
/* We assume jcmaster.c already validated the progressive scan parameters. */
/* Select execution routines */
if (cinfo->progressive_mode) {
if (cinfo->Ah == 0) {
if (cinfo->Ss == 0)
entropy->pub.encode_mcu = encode_mcu_DC_first;
else
entropy->pub.encode_mcu = encode_mcu_AC_first;
} else {
if (cinfo->Ss == 0)
entropy->pub.encode_mcu = encode_mcu_DC_refine;
else
entropy->pub.encode_mcu = encode_mcu_AC_refine;
}
} else
entropy->pub.encode_mcu = encode_mcu;
/* Allocate & initialize requested statistics areas */
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
/* DC needs no table for refinement scan */
if (cinfo->progressive_mode == 0 || (cinfo->Ss == 0 && cinfo->Ah == 0)) {
tbl = compptr->dc_tbl_no;
if (tbl < 0 || tbl >= NUM_ARITH_TBLS)
ERREXIT1(cinfo, JERR_NO_ARITH_TABLE, tbl);
if (entropy->dc_stats[tbl] == NULL)
entropy->dc_stats[tbl] = (unsigned char *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, DC_STAT_BINS);
MEMZERO(entropy->dc_stats[tbl], DC_STAT_BINS);
/* Initialize DC predictions to 0 */
entropy->last_dc_val[ci] = 0;
entropy->dc_context[ci] = 0;
}
/* AC needs no table when not present */
if (cinfo->progressive_mode == 0 || cinfo->Se) {
tbl = compptr->ac_tbl_no;
if (tbl < 0 || tbl >= NUM_ARITH_TBLS)
ERREXIT1(cinfo, JERR_NO_ARITH_TABLE, tbl);
if (entropy->ac_stats[tbl] == NULL)
entropy->ac_stats[tbl] = (unsigned char *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, AC_STAT_BINS);
MEMZERO(entropy->ac_stats[tbl], AC_STAT_BINS);
#ifdef CALCULATE_SPECTRAL_CONDITIONING
if (cinfo->progressive_mode)
/* Section G.1.3.2: Set appropriate arithmetic conditioning value Kx */
cinfo->arith_ac_K[tbl] = cinfo->Ss + ((8 + cinfo->Se - cinfo->Ss) >> 4);
#endif
}
}
/* Initialize arithmetic encoding variables */
entropy->c = 0;
entropy->a = 0x10000L;
entropy->sc = 0;
entropy->zc = 0;
entropy->ct = 11;
entropy->buffer = -1; /* empty */
/* Initialize restart stuff */
entropy->restarts_to_go = cinfo->restart_interval;
entropy->next_restart_num = 0;
}
/*
* Module initialization routine for arithmetic entropy encoding.
*/
GLOBAL(void)
jinit_arith_encoder (j_compress_ptr cinfo)
{
arith_entropy_ptr entropy;
int i;
entropy = (arith_entropy_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(arith_entropy_encoder));
cinfo->entropy = (struct jpeg_entropy_encoder *) entropy;
entropy->pub.start_pass = start_pass;
entropy->pub.finish_pass = finish_pass;
/* Mark tables unallocated */
for (i = 0; i < NUM_ARITH_TBLS; i++) {
entropy->dc_stats[i] = NULL;
entropy->ac_stats[i] = NULL;
}
/* Initialize index for fixed probability estimation */
entropy->fixed_bin[0] = 113;
}

View File

@@ -1,7 +1,7 @@
/*
* jccoefct.c
*
* Copyright (C) 1994-1996, Thomas G. Lane.
* Copyright (C) 1994-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -135,8 +135,8 @@ start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
* per call, ie, v_samp_factor block rows for each component in the image.
* Returns TRUE if the iMCU row is completed, FALSE if suspended.
*
* NB: input_buf contains a plane for each component in image.
* For single pass, this is the same as the components in the scan.
* NB: input_buf contains a plane for each component in image,
* which we index according to the component's SOF position.
*/
METHODDEF(boolean)
@@ -175,7 +175,8 @@ compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
if (coef->iMCU_row_num < last_iMCU_row ||
yoffset+yindex < compptr->last_row_height) {
(*cinfo->fdct->forward_DCT) (cinfo, compptr,
input_buf[ci], coef->MCU_buffer[blkn],
input_buf[compptr->component_index],
coef->MCU_buffer[blkn],
ypos, xpos, (JDIMENSION) blockcnt);
if (blockcnt < compptr->MCU_width) {
/* Create some dummy blocks at the right edge of the image. */

150
jccolor.c
View File

@@ -2,6 +2,8 @@
* jccolor.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
* Copyright 2009 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.
*
@@ -11,6 +13,7 @@
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jsimd.h"
/* Private subobject */
@@ -78,6 +81,74 @@ typedef my_color_converter * my_cconvert_ptr;
#define TABLE_SIZE (8*(MAXJSAMPLE+1))
#if BITS_IN_JSAMPLE == 8
static const unsigned char red_lut[256] = {
0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 3 , 3 , 3 , 4 , 4 , 4 , 4 ,
5 , 5 , 5 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 9 , 9 , 9 ,
10, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14,
14, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19,
19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 24,
24, 24, 25, 25, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 28,
29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 32, 32, 32, 33, 33, 33,
33, 34, 34, 34, 35, 35, 35, 36, 36, 36, 36, 37, 37, 37, 38, 38,
38, 39, 39, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 42, 42, 43,
43, 43, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 47, 47, 47, 48,
48, 48, 48, 49, 49, 49, 50, 50, 50, 51, 51, 51, 51, 52, 52, 52,
53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 56, 56, 56, 57, 57, 57,
57, 58, 58, 58, 59, 59, 59, 60, 60, 60, 60, 61, 61, 61, 62, 62,
62, 62, 63, 63, 63, 64, 64, 64, 65, 65, 65, 65, 66, 66, 66, 67,
67, 67, 68, 68, 68, 68, 69, 69, 69, 70, 70, 70, 71, 71, 71, 71,
72, 72, 72, 73, 73, 73, 74, 74, 74, 74, 75, 75, 75, 76, 76, 76
};
static const unsigned char green_lut[256] = {
0 , 1 , 1 , 2 , 2 , 3 , 4 , 4 , 5 , 5 , 6 , 6 ,
7 , 8 , 8 , 9 , 9 , 10 , 11 , 11 , 12 , 12 , 13 , 14 ,
14 , 15 , 15 , 16 , 16 , 17 , 18 , 18 , 19 , 19 , 20 , 21 ,
21 , 22 , 22 , 23 , 23 , 24 , 25 , 25 , 26 , 26 , 27 , 28 ,
28 , 29 , 29 , 30 , 31 , 31 , 32 , 32 , 33 , 33 , 34 , 35 ,
35 , 36 , 36 , 37 , 38 , 38 , 39 , 39 , 40 , 41 , 41 , 42 ,
42 , 43 , 43 , 44 , 45 , 45 , 46 , 46 , 47 , 48 , 48 , 49 ,
49 , 50 , 50 , 51 , 52 , 52 , 53 , 53 , 54 , 55 , 55 , 56 ,
56 , 57 , 58 , 58 , 59 , 59 , 60 , 60 , 61 , 62 , 62 , 63 ,
63 , 64 , 65 , 65 , 66 , 66 , 67 , 68 , 68 , 69 , 69 , 70 ,
70 , 71 , 72 , 72 , 73 , 73 , 74 , 75 , 75 , 76 , 76 , 77 ,
77 , 78 , 79 , 79 , 80 , 80 , 81 , 82 , 82 , 83 , 83 , 84 ,
85 , 85 , 86 , 86 , 87 , 87 , 88 , 89 , 89 , 90 , 90 , 91 ,
92 , 92 , 93 , 93 , 94 , 95 , 95 , 96 , 96 , 97 , 97 , 98 ,
99 , 99 , 100, 100, 101, 102, 102, 103, 103, 104, 104, 105,
106, 106, 107, 107, 108, 109, 109, 110, 110, 111, 112, 112,
113, 113, 114, 114, 115, 116, 116, 117, 117, 118, 119, 119,
120, 120, 121, 122, 122, 123, 123, 124, 124, 125, 126, 126,
127, 127, 128, 129, 129, 130, 130, 131, 131, 132, 133, 133,
34, 134, 135, 136, 136, 137, 137, 138, 139, 139, 140, 140,
141, 141, 142, 143, 143, 144, 144, 145, 146, 146, 147, 147,
148, 149, 149, 150
};
static const unsigned char blue_lut[256] = {
0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 2 , 2 ,
2 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 4 ,
4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 ,
5 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 7 ,
7 , 7 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 9 ,
9 , 9 , 9 , 9 , 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11,
11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13,
13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14,
15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18,
18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20,
20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22,
22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24,
24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25,
26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27,
27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29
};
#endif
/*
* Initialize for RGB->YCC colorspace conversion.
*/
@@ -146,10 +217,10 @@ rgb_ycc_convert (j_compress_ptr cinfo,
outptr2 = output_buf[2][output_row];
output_row++;
for (col = 0; col < num_cols; col++) {
r = GETJSAMPLE(inptr[RGB_RED]);
g = GETJSAMPLE(inptr[RGB_GREEN]);
b = GETJSAMPLE(inptr[RGB_BLUE]);
inptr += RGB_PIXELSIZE;
r = GETJSAMPLE(inptr[rgb_red[cinfo->in_color_space]]);
g = GETJSAMPLE(inptr[rgb_green[cinfo->in_color_space]]);
b = GETJSAMPLE(inptr[rgb_blue[cinfo->in_color_space]]);
inptr += rgb_pixelsize[cinfo->in_color_space];
/* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
* must be too; we do not need an explicit range-limiting operation.
* Hence the value being shifted is never negative, and we don't
@@ -188,26 +259,36 @@ rgb_gray_convert (j_compress_ptr cinfo,
JDIMENSION output_row, int num_rows)
{
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
register int r, g, b;
#if BITS_IN_JSAMPLE != 8
register INT32 * ctab = cconvert->rgb_ycc_tab;
#endif
register JSAMPROW inptr;
register JSAMPROW outptr;
JSAMPLE *maxoutptr;
register JDIMENSION col;
JDIMENSION num_cols = cinfo->image_width;
int rindex = rgb_red[cinfo->in_color_space];
int gindex = rgb_green[cinfo->in_color_space];
int bindex = rgb_blue[cinfo->in_color_space];
int rgbstride = rgb_pixelsize[cinfo->in_color_space];
while (--num_rows >= 0) {
inptr = *input_buf++;
outptr = output_buf[0][output_row];
maxoutptr = &outptr[num_cols];
output_row++;
for (col = 0; col < num_cols; col++) {
r = GETJSAMPLE(inptr[RGB_RED]);
g = GETJSAMPLE(inptr[RGB_GREEN]);
b = GETJSAMPLE(inptr[RGB_BLUE]);
inptr += RGB_PIXELSIZE;
for (; outptr < maxoutptr; outptr++, inptr += rgbstride) {
/* Y */
outptr[col] = (JSAMPLE)
((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
>> SCALEBITS);
#if BITS_IN_JSAMPLE == 8
*outptr = red_lut[inptr[rindex]] + green_lut[inptr[gindex]]
+ blue_lut[inptr[bindex]];
#else
*outptr = (JSAMPLE)
((ctab[GETJSAMPLE(inptr[rindex])+R_Y_OFF]
+ ctab[GETJSAMPLE(inptr[gindex])+G_Y_OFF]
+ ctab[GETJSAMPLE(inptr[bindex])+B_Y_OFF])
>> SCALEBITS);
#endif
}
}
}
@@ -368,11 +449,15 @@ jinit_color_converter (j_compress_ptr cinfo)
break;
case JCS_RGB:
#if RGB_PIXELSIZE != 3
if (cinfo->input_components != RGB_PIXELSIZE)
case JCS_EXT_RGB:
case JCS_EXT_RGBX:
case JCS_EXT_BGR:
case JCS_EXT_BGRX:
case JCS_EXT_XBGR:
case JCS_EXT_XRGB:
if (cinfo->input_components != rgb_pixelsize[cinfo->in_color_space])
ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
break;
#endif /* else share code with YCbCr */
case JCS_YCbCr:
if (cinfo->input_components != 3)
@@ -398,7 +483,13 @@ jinit_color_converter (j_compress_ptr cinfo)
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
if (cinfo->in_color_space == JCS_GRAYSCALE)
cconvert->pub.color_convert = grayscale_convert;
else if (cinfo->in_color_space == JCS_RGB) {
else if (cinfo->in_color_space == JCS_RGB ||
cinfo->in_color_space == JCS_EXT_RGB ||
cinfo->in_color_space == JCS_EXT_RGBX ||
cinfo->in_color_space == JCS_EXT_BGR ||
cinfo->in_color_space == JCS_EXT_BGRX ||
cinfo->in_color_space == JCS_EXT_XBGR ||
cinfo->in_color_space == JCS_EXT_XRGB) {
cconvert->pub.start_pass = rgb_ycc_start;
cconvert->pub.color_convert = rgb_gray_convert;
} else if (cinfo->in_color_space == JCS_YCbCr)
@@ -408,9 +499,16 @@ jinit_color_converter (j_compress_ptr cinfo)
break;
case JCS_RGB:
case JCS_EXT_RGB:
case JCS_EXT_RGBX:
case JCS_EXT_BGR:
case JCS_EXT_BGRX:
case JCS_EXT_XBGR:
case JCS_EXT_XRGB:
if (cinfo->num_components != 3)
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
if (cinfo->in_color_space == JCS_RGB && RGB_PIXELSIZE == 3)
if (cinfo->in_color_space == cinfo->jpeg_color_space &&
rgb_pixelsize[cinfo->in_color_space] == 3)
cconvert->pub.color_convert = null_convert;
else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
@@ -419,9 +517,19 @@ jinit_color_converter (j_compress_ptr cinfo)
case JCS_YCbCr:
if (cinfo->num_components != 3)
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
if (cinfo->in_color_space == JCS_RGB) {
cconvert->pub.start_pass = rgb_ycc_start;
cconvert->pub.color_convert = rgb_ycc_convert;
if (cinfo->in_color_space == JCS_RGB ||
cinfo->in_color_space == JCS_EXT_RGB ||
cinfo->in_color_space == JCS_EXT_RGBX ||
cinfo->in_color_space == JCS_EXT_BGR ||
cinfo->in_color_space == JCS_EXT_BGRX ||
cinfo->in_color_space == JCS_EXT_XBGR ||
cinfo->in_color_space == JCS_EXT_XRGB) {
if (jsimd_can_rgb_ycc())
cconvert->pub.color_convert = jsimd_rgb_ycc_convert;
else {
cconvert->pub.start_pass = rgb_ycc_start;
cconvert->pub.color_convert = rgb_ycc_convert;
}
} else if (cinfo->in_color_space == JCS_YCbCr)
cconvert->pub.color_convert = null_convert;
else

View File

@@ -2,6 +2,8 @@
* jcdctmgr.c
*
* Copyright (C) 1994-1996, Thomas G. Lane.
* Copyright (C) 1999-2006, MIYASAKA Masaru.
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -15,15 +17,35 @@
#include "jinclude.h"
#include "jpeglib.h"
#include "jdct.h" /* Private declarations for DCT subsystem */
#include "jsimddct.h"
/* Private subobject for this module */
typedef JMETHOD(void, forward_DCT_method_ptr, (DCTELEM * data));
typedef JMETHOD(void, float_DCT_method_ptr, (FAST_FLOAT * data));
typedef JMETHOD(void, convsamp_method_ptr,
(JSAMPARRAY sample_data, JDIMENSION start_col,
DCTELEM * workspace));
typedef JMETHOD(void, float_convsamp_method_ptr,
(JSAMPARRAY sample_data, JDIMENSION start_col,
FAST_FLOAT *workspace));
typedef JMETHOD(void, quantize_method_ptr,
(JCOEFPTR coef_block, DCTELEM * divisors,
DCTELEM * workspace));
typedef JMETHOD(void, float_quantize_method_ptr,
(JCOEFPTR coef_block, FAST_FLOAT * divisors,
FAST_FLOAT * workspace));
typedef struct {
struct jpeg_forward_dct pub; /* public fields */
/* Pointer to the DCT routine actually in use */
forward_DCT_method_ptr do_dct;
forward_DCT_method_ptr dct;
convsamp_method_ptr convsamp;
quantize_method_ptr quantize;
/* The actual post-DCT divisors --- not identical to the quant table
* entries, because of scaling (especially for an unnormalized DCT).
@@ -31,16 +53,144 @@ typedef struct {
*/
DCTELEM * divisors[NUM_QUANT_TBLS];
/* work area for FDCT subroutine */
DCTELEM * workspace;
#ifdef DCT_FLOAT_SUPPORTED
/* Same as above for the floating-point case. */
float_DCT_method_ptr do_float_dct;
float_DCT_method_ptr float_dct;
float_convsamp_method_ptr float_convsamp;
float_quantize_method_ptr float_quantize;
FAST_FLOAT * float_divisors[NUM_QUANT_TBLS];
FAST_FLOAT * float_workspace;
#endif
} my_fdct_controller;
typedef my_fdct_controller * my_fdct_ptr;
/*
* Find the highest bit in an integer through binary search.
*/
LOCAL(int)
flss (UINT16 val)
{
int bit;
bit = 16;
if (!val)
return 0;
if (!(val & 0xff00)) {
bit -= 8;
val <<= 8;
}
if (!(val & 0xf000)) {
bit -= 4;
val <<= 4;
}
if (!(val & 0xc000)) {
bit -= 2;
val <<= 2;
}
if (!(val & 0x8000)) {
bit -= 1;
val <<= 1;
}
return bit;
}
/*
* Compute values to do a division using reciprocal.
*
* This implementation is based on an algorithm described in
* "How to optimize for the Pentium family of microprocessors"
* (http://www.agner.org/assem/).
* More information about the basic algorithm can be found in
* the paper "Integer Division Using Reciprocals" by Robert Alverson.
*
* The basic idea is to replace x/d by x * d^-1. In order to store
* d^-1 with enough precision we shift it left a few places. It turns
* out that this algoright gives just enough precision, and also fits
* into DCTELEM:
*
* b = (the number of significant bits in divisor) - 1
* r = (word size) + b
* f = 2^r / divisor
*
* f will not be an integer for most cases, so we need to compensate
* for the rounding error introduced:
*
* no fractional part:
*
* result = input >> r
*
* fractional part of f < 0.5:
*
* round f down to nearest integer
* result = ((input + 1) * f) >> r
*
* fractional part of f > 0.5:
*
* round f up to nearest integer
* result = (input * f) >> r
*
* This is the original algorithm that gives truncated results. But we
* want properly rounded results, so we replace "input" with
* "input + divisor/2".
*
* In order to allow SIMD implementations we also tweak the values to
* allow the same calculation to be made at all times:
*
* dctbl[0] = f rounded to nearest integer
* dctbl[1] = divisor / 2 (+ 1 if fractional part of f < 0.5)
* dctbl[2] = 1 << ((word size) * 2 - r)
* dctbl[3] = r - (word size)
*
* dctbl[2] is for stupid instruction sets where the shift operation
* isn't member wise (e.g. MMX).
*
* The reason dctbl[2] and dctbl[3] reduce the shift with (word size)
* is that most SIMD implementations have a "multiply and store top
* half" operation.
*
* Lastly, we store each of the values in their own table instead
* of in a consecutive manner, yet again in order to allow SIMD
* routines.
*/
LOCAL(void)
compute_reciprocal (UINT16 divisor, DCTELEM * dtbl)
{
UDCTELEM2 fq, fr;
UDCTELEM c;
int b, r;
b = flss(divisor) - 1;
r = sizeof(DCTELEM) * 8 + b;
fq = ((UDCTELEM2)1 << r) / divisor;
fr = ((UDCTELEM2)1 << r) % divisor;
c = divisor / 2; /* for rounding */
if (fr == 0) { /* divisor is power of two */
/* fq will be one bit too large to fit in DCTELEM, so adjust */
fq >>= 1;
r--;
} else if (fr <= (divisor / 2)) { /* fractional part is < 0.5 */
c++;
} else { /* fractional part is > 0.5 */
fq++;
}
dtbl[DCTSIZE2 * 0] = (DCTELEM) fq; /* reciprocal */
dtbl[DCTSIZE2 * 1] = (DCTELEM) c; /* correction + roundfactor */
dtbl[DCTSIZE2 * 2] = (DCTELEM) (1 << (sizeof(DCTELEM)*8*2 - r)); /* scale */
dtbl[DCTSIZE2 * 3] = (DCTELEM) r - sizeof(DCTELEM)*8; /* shift */
}
/*
* Initialize for a processing pass.
* Verify that all referenced Q-tables are present, and set up
@@ -78,11 +228,11 @@ start_pass_fdctmgr (j_compress_ptr cinfo)
if (fdct->divisors[qtblno] == NULL) {
fdct->divisors[qtblno] = (DCTELEM *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
DCTSIZE2 * SIZEOF(DCTELEM));
(DCTSIZE2 * 4) * SIZEOF(DCTELEM));
}
dtbl = fdct->divisors[qtblno];
for (i = 0; i < DCTSIZE2; i++) {
dtbl[i] = ((DCTELEM) qtbl->quantval[i]) << 3;
compute_reciprocal(qtbl->quantval[i] << 3, &dtbl[i]);
}
break;
#endif
@@ -112,14 +262,14 @@ start_pass_fdctmgr (j_compress_ptr cinfo)
if (fdct->divisors[qtblno] == NULL) {
fdct->divisors[qtblno] = (DCTELEM *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
DCTSIZE2 * SIZEOF(DCTELEM));
(DCTSIZE2 * 4) * SIZEOF(DCTELEM));
}
dtbl = fdct->divisors[qtblno];
for (i = 0; i < DCTSIZE2; i++) {
dtbl[i] = (DCTELEM)
compute_reciprocal(
DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
(INT32) aanscales[i]),
CONST_BITS-3);
CONST_BITS-3), &dtbl[i]);
}
}
break;
@@ -168,6 +318,77 @@ start_pass_fdctmgr (j_compress_ptr cinfo)
}
/*
* Load data into workspace, applying unsigned->signed conversion.
*/
METHODDEF(void)
convsamp (JSAMPARRAY sample_data, JDIMENSION start_col, DCTELEM * workspace)
{
register DCTELEM *workspaceptr;
register JSAMPROW elemptr;
register int elemr;
workspaceptr = workspace;
for (elemr = 0; elemr < DCTSIZE; elemr++) {
elemptr = sample_data[elemr] + start_col;
#if DCTSIZE == 8 /* unroll the inner loop */
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
#else
{
register int elemc;
for (elemc = DCTSIZE; elemc > 0; elemc--)
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
}
#endif
}
}
/*
* Quantize/descale the coefficients, and store into coef_blocks[].
*/
METHODDEF(void)
quantize (JCOEFPTR coef_block, DCTELEM * divisors, DCTELEM * workspace)
{
int i;
DCTELEM temp;
UDCTELEM recip, corr, shift;
UDCTELEM2 product;
JCOEFPTR output_ptr = coef_block;
for (i = 0; i < DCTSIZE2; i++) {
temp = workspace[i];
recip = divisors[i + DCTSIZE2 * 0];
corr = divisors[i + DCTSIZE2 * 1];
shift = divisors[i + DCTSIZE2 * 3];
if (temp < 0) {
temp = -temp;
product = (UDCTELEM2)(temp + corr) * recip;
product >>= shift + sizeof(DCTELEM)*8;
temp = product;
temp = -temp;
} else {
product = (UDCTELEM2)(temp + corr) * recip;
product >>= shift + sizeof(DCTELEM)*8;
temp = product;
}
output_ptr[i] = (JCOEF) temp;
}
}
/*
* Perform forward DCT on one or more blocks of a component.
*
@@ -185,87 +406,87 @@ forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
{
/* This routine is heavily used, so it's worth coding it tightly. */
my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
forward_DCT_method_ptr do_dct = fdct->do_dct;
DCTELEM * divisors = fdct->divisors[compptr->quant_tbl_no];
DCTELEM workspace[DCTSIZE2]; /* work area for FDCT subroutine */
DCTELEM * workspace;
JDIMENSION bi;
/* Make sure the compiler doesn't look up these every pass */
forward_DCT_method_ptr do_dct = fdct->dct;
convsamp_method_ptr do_convsamp = fdct->convsamp;
quantize_method_ptr do_quantize = fdct->quantize;
workspace = fdct->workspace;
sample_data += start_row; /* fold in the vertical offset once */
for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
/* Load data into workspace, applying unsigned->signed conversion */
{ register DCTELEM *workspaceptr;
register JSAMPROW elemptr;
register int elemr;
workspaceptr = workspace;
for (elemr = 0; elemr < DCTSIZE; elemr++) {
elemptr = sample_data[elemr] + start_col;
#if DCTSIZE == 8 /* unroll the inner loop */
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
#else
{ register int elemc;
for (elemc = DCTSIZE; elemc > 0; elemc--) {
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
}
}
#endif
}
}
(*do_convsamp) (sample_data, start_col, workspace);
/* Perform the DCT */
(*do_dct) (workspace);
/* Quantize/descale the coefficients, and store into coef_blocks[] */
{ register DCTELEM temp, qval;
register int i;
register JCOEFPTR output_ptr = coef_blocks[bi];
for (i = 0; i < DCTSIZE2; i++) {
qval = divisors[i];
temp = workspace[i];
/* Divide the coefficient value by qval, ensuring proper rounding.
* Since C does not specify the direction of rounding for negative
* quotients, we have to force the dividend positive for portability.
*
* In most files, at least half of the output values will be zero
* (at default quantization settings, more like three-quarters...)
* so we should ensure that this case is fast. On many machines,
* a comparison is enough cheaper than a divide to make a special test
* a win. Since both inputs will be nonnegative, we need only test
* for a < b to discover whether a/b is 0.
* If your machine's division is fast enough, define FAST_DIVIDE.
*/
#ifdef FAST_DIVIDE
#define DIVIDE_BY(a,b) a /= b
#else
#define DIVIDE_BY(a,b) if (a >= b) a /= b; else a = 0
#endif
if (temp < 0) {
temp = -temp;
temp += qval>>1; /* for rounding */
DIVIDE_BY(temp, qval);
temp = -temp;
} else {
temp += qval>>1; /* for rounding */
DIVIDE_BY(temp, qval);
}
output_ptr[i] = (JCOEF) temp;
}
}
(*do_quantize) (coef_blocks[bi], divisors, workspace);
}
}
#ifdef DCT_FLOAT_SUPPORTED
METHODDEF(void)
convsamp_float (JSAMPARRAY sample_data, JDIMENSION start_col, FAST_FLOAT * workspace)
{
register FAST_FLOAT *workspaceptr;
register JSAMPROW elemptr;
register int elemr;
workspaceptr = workspace;
for (elemr = 0; elemr < DCTSIZE; elemr++) {
elemptr = sample_data[elemr] + start_col;
#if DCTSIZE == 8 /* unroll the inner loop */
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
#else
{
register int elemc;
for (elemc = DCTSIZE; elemc > 0; elemc--)
*workspaceptr++ = (FAST_FLOAT)
(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
}
#endif
}
}
METHODDEF(void)
quantize_float (JCOEFPTR coef_block, FAST_FLOAT * divisors, FAST_FLOAT * workspace)
{
register FAST_FLOAT temp;
register int i;
register JCOEFPTR output_ptr = coef_block;
for (i = 0; i < DCTSIZE2; i++) {
/* Apply the quantization and scaling factor */
temp = workspace[i] * divisors[i];
/* Round to nearest integer.
* Since C does not specify the direction of rounding for negative
* quotients, we have to force the dividend positive for portability.
* The maximum coefficient size is +-16K (for 12-bit data), so this
* code should work for either 16-bit or 32-bit ints.
*/
output_ptr[i] = (JCOEF) ((int) (temp + (FAST_FLOAT) 16384.5) - 16384);
}
}
METHODDEF(void)
forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
@@ -275,62 +496,28 @@ forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
{
/* This routine is heavily used, so it's worth coding it tightly. */
my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
float_DCT_method_ptr do_dct = fdct->do_float_dct;
FAST_FLOAT * divisors = fdct->float_divisors[compptr->quant_tbl_no];
FAST_FLOAT workspace[DCTSIZE2]; /* work area for FDCT subroutine */
FAST_FLOAT * workspace;
JDIMENSION bi;
/* Make sure the compiler doesn't look up these every pass */
float_DCT_method_ptr do_dct = fdct->float_dct;
float_convsamp_method_ptr do_convsamp = fdct->float_convsamp;
float_quantize_method_ptr do_quantize = fdct->float_quantize;
workspace = fdct->float_workspace;
sample_data += start_row; /* fold in the vertical offset once */
for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
/* Load data into workspace, applying unsigned->signed conversion */
{ register FAST_FLOAT *workspaceptr;
register JSAMPROW elemptr;
register int elemr;
workspaceptr = workspace;
for (elemr = 0; elemr < DCTSIZE; elemr++) {
elemptr = sample_data[elemr] + start_col;
#if DCTSIZE == 8 /* unroll the inner loop */
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
#else
{ register int elemc;
for (elemc = DCTSIZE; elemc > 0; elemc--) {
*workspaceptr++ = (FAST_FLOAT)
(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
}
}
#endif
}
}
(*do_convsamp) (sample_data, start_col, workspace);
/* Perform the DCT */
(*do_dct) (workspace);
/* Quantize/descale the coefficients, and store into coef_blocks[] */
{ register FAST_FLOAT temp;
register int i;
register JCOEFPTR output_ptr = coef_blocks[bi];
for (i = 0; i < DCTSIZE2; i++) {
/* Apply the quantization and scaling factor */
temp = workspace[i] * divisors[i];
/* Round to nearest integer.
* Since C does not specify the direction of rounding for negative
* quotients, we have to force the dividend positive for portability.
* The maximum coefficient size is +-16K (for 12-bit data), so this
* code should work for either 16-bit or 32-bit ints.
*/
output_ptr[i] = (JCOEF) ((int) (temp + (FAST_FLOAT) 16384.5) - 16384);
}
}
(*do_quantize) (coef_blocks[bi], divisors, workspace);
}
}
@@ -353,23 +540,33 @@ jinit_forward_dct (j_compress_ptr cinfo)
cinfo->fdct = (struct jpeg_forward_dct *) fdct;
fdct->pub.start_pass = start_pass_fdctmgr;
/* First determine the DCT... */
switch (cinfo->dct_method) {
#ifdef DCT_ISLOW_SUPPORTED
case JDCT_ISLOW:
fdct->pub.forward_DCT = forward_DCT;
fdct->do_dct = jpeg_fdct_islow;
if (jsimd_can_fdct_islow())
fdct->dct = jsimd_fdct_islow;
else
fdct->dct = jpeg_fdct_islow;
break;
#endif
#ifdef DCT_IFAST_SUPPORTED
case JDCT_IFAST:
fdct->pub.forward_DCT = forward_DCT;
fdct->do_dct = jpeg_fdct_ifast;
if (jsimd_can_fdct_ifast())
fdct->dct = jsimd_fdct_ifast;
else
fdct->dct = jpeg_fdct_ifast;
break;
#endif
#ifdef DCT_FLOAT_SUPPORTED
case JDCT_FLOAT:
fdct->pub.forward_DCT = forward_DCT_float;
fdct->do_float_dct = jpeg_fdct_float;
if (jsimd_can_fdct_float())
fdct->float_dct = jsimd_fdct_float;
else
fdct->float_dct = jpeg_fdct_float;
break;
#endif
default:
@@ -377,6 +574,54 @@ jinit_forward_dct (j_compress_ptr cinfo)
break;
}
/* ...then the supporting stages. */
switch (cinfo->dct_method) {
#ifdef DCT_ISLOW_SUPPORTED
case JDCT_ISLOW:
#endif
#ifdef DCT_IFAST_SUPPORTED
case JDCT_IFAST:
#endif
#if defined(DCT_ISLOW_SUPPORTED) || defined(DCT_IFAST_SUPPORTED)
if (jsimd_can_convsamp())
fdct->convsamp = jsimd_convsamp;
else
fdct->convsamp = convsamp;
if (jsimd_can_quantize())
fdct->quantize = jsimd_quantize;
else
fdct->quantize = quantize;
break;
#endif
#ifdef DCT_FLOAT_SUPPORTED
case JDCT_FLOAT:
if (jsimd_can_convsamp_float())
fdct->float_convsamp = jsimd_convsamp_float;
else
fdct->float_convsamp = convsamp_float;
if (jsimd_can_quantize_float())
fdct->float_quantize = jsimd_quantize_float;
else
fdct->float_quantize = quantize_float;
break;
#endif
default:
ERREXIT(cinfo, JERR_NOT_COMPILED);
break;
}
/* Allocate workspace memory */
#ifdef DCT_FLOAT_SUPPORTED
if (cinfo->dct_method == JDCT_FLOAT)
fdct->float_workspace = (FAST_FLOAT *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(FAST_FLOAT) * DCTSIZE2);
else
#endif
fdct->workspace = (DCTELEM *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(DCTELEM) * DCTSIZE2);
/* Mark divisor tables unallocated */
for (i = 0; i < NUM_QUANT_TBLS; i++) {
fdct->divisors[i] = NULL;

476
jchuff.c
View File

@@ -1,7 +1,7 @@
/*
* jchuff.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Copyright (C) 1991-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -14,11 +14,33 @@
* permanent JPEG objects only upon successful completion of an MCU.
*/
/* Modifications:
* Copyright (C)2007 Sun Microsystems, Inc.
* Copyright (C)2009 D. R. Commander
*
* This library is free software and may be redistributed and/or modified under
* the terms of the wxWindows Library License, Version 3.1 or (at your option)
* any later version. The full license is in the LICENSE.txt file included
* with this distribution.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* wxWindows Library License for more details.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jchuff.h" /* Declarations shared with jcphuff.c */
#include <limits.h>
static unsigned char jpeg_first_bit_table[65536];
static int jpeg_first_bit_table_init=0;
#ifndef min
#define min(a,b) ((a)<(b)?(a):(b))
#endif
/* Expanded entropy encoder object for Huffman encoding.
*
@@ -27,7 +49,7 @@
*/
typedef struct {
INT32 put_buffer; /* current bit-accumulation buffer */
size_t put_buffer; /* current bit-accumulation buffer */
int put_bits; /* # of bits now in it */
int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
} savable_state;
@@ -125,16 +147,14 @@ start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics)
compptr = cinfo->cur_comp_info[ci];
dctbl = compptr->dc_tbl_no;
actbl = compptr->ac_tbl_no;
/* Make sure requested tables are present */
/* (In gather mode, tables need not be allocated yet) */
if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS ||
(cinfo->dc_huff_tbl_ptrs[dctbl] == NULL && !gather_statistics))
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl);
if (actbl < 0 || actbl >= NUM_HUFF_TBLS ||
(cinfo->ac_huff_tbl_ptrs[actbl] == NULL && !gather_statistics))
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, actbl);
if (gather_statistics) {
#ifdef ENTROPY_OPT_SUPPORTED
/* Check for invalid table indexes */
/* (make_c_derived_tbl does this in the other path) */
if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS)
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl);
if (actbl < 0 || actbl >= NUM_HUFF_TBLS)
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, actbl);
/* Allocate and zero the statistics tables */
/* Note that jpeg_gen_optimal_table expects 257 entries in each table! */
if (entropy->dc_count_ptrs[dctbl] == NULL)
@@ -151,9 +171,9 @@ start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics)
} else {
/* Compute derived values for Huffman tables */
/* We may do this more than once for a table, but it's not expensive */
jpeg_make_c_derived_tbl(cinfo, cinfo->dc_huff_tbl_ptrs[dctbl],
jpeg_make_c_derived_tbl(cinfo, TRUE, dctbl,
& entropy->dc_derived_tbls[dctbl]);
jpeg_make_c_derived_tbl(cinfo, cinfo->ac_huff_tbl_ptrs[actbl],
jpeg_make_c_derived_tbl(cinfo, FALSE, actbl,
& entropy->ac_derived_tbls[actbl]);
}
/* Initialize DC predictions to 0 */
@@ -161,6 +181,7 @@ start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics)
}
/* Initialize bit buffer to empty */
entropy->saved.put_buffer = 0;
entropy->saved.put_bits = 0;
@@ -172,19 +193,34 @@ start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics)
/*
* Compute the derived values for a Huffman table.
* This routine also performs some validation checks on the table.
*
* Note this is also used by jcphuff.c.
*/
GLOBAL(void)
jpeg_make_c_derived_tbl (j_compress_ptr cinfo, JHUFF_TBL * htbl,
jpeg_make_c_derived_tbl (j_compress_ptr cinfo, boolean isDC, int tblno,
c_derived_tbl ** pdtbl)
{
JHUFF_TBL *htbl;
c_derived_tbl *dtbl;
int p, i, l, lastp, si;
int p, i, l, lastp, si, maxsymbol;
char huffsize[257];
unsigned int huffcode[257];
unsigned int code;
/* Note that huffsize[] and huffcode[] are filled in code-length order,
* paralleling the order of the symbols themselves in htbl->huffval[].
*/
/* Find the input Huffman table */
if (tblno < 0 || tblno >= NUM_HUFF_TBLS)
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
htbl =
isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno];
if (htbl == NULL)
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
/* Allocate a workspace if we haven't already done so. */
if (*pdtbl == NULL)
*pdtbl = (c_derived_tbl *)
@@ -193,19 +229,21 @@ jpeg_make_c_derived_tbl (j_compress_ptr cinfo, JHUFF_TBL * htbl,
dtbl = *pdtbl;
/* Figure C.1: make table of Huffman code length for each symbol */
/* Note that this is in code-length order. */
p = 0;
for (l = 1; l <= 16; l++) {
for (i = 1; i <= (int) htbl->bits[l]; i++)
i = (int) htbl->bits[l];
if (i < 0 || p + i > 256) /* protect against table overrun */
ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
while (i--)
huffsize[p++] = (char) l;
}
huffsize[p] = 0;
lastp = p;
/* Figure C.2: generate the codes themselves */
/* Note that this is in code-length order. */
/* We also validate that the counts represent a legal Huffman code tree. */
code = 0;
si = huffsize[0];
p = 0;
@@ -214,6 +252,11 @@ jpeg_make_c_derived_tbl (j_compress_ptr cinfo, JHUFF_TBL * htbl,
huffcode[p++] = code;
code++;
}
/* code is now 1 more than the last code used for codelength si; but
* it must still fit in si bits, since no code is allowed to be all ones.
*/
if (((INT32) code) >= (((INT32) 1) << si))
ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
code <<= 1;
si++;
}
@@ -221,14 +264,34 @@ jpeg_make_c_derived_tbl (j_compress_ptr cinfo, JHUFF_TBL * htbl,
/* Figure C.3: generate encoding tables */
/* These are code and size indexed by symbol value */
/* Set any codeless symbols to have code length 0;
* this allows emit_bits to detect any attempt to emit such symbols.
/* Set all codeless symbols to have code length 0;
* this lets us detect duplicate VAL entries here, and later
* allows emit_bits to detect any attempt to emit such symbols.
*/
MEMZERO(dtbl->ehufsi, SIZEOF(dtbl->ehufsi));
/* This is also a convenient place to check for out-of-range
* and duplicated VAL entries. We allow 0..255 for AC symbols
* but only 0..15 for DC. (We could constrain them further
* based on data depth and mode, but this seems enough.)
*/
maxsymbol = isDC ? 15 : 255;
for (p = 0; p < lastp; p++) {
dtbl->ehufco[htbl->huffval[p]] = huffcode[p];
dtbl->ehufsi[htbl->huffval[p]] = huffsize[p];
i = htbl->huffval[p];
if (i < 0 || i > maxsymbol || dtbl->ehufsi[i])
ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
dtbl->ehufco[i] = huffcode[p];
dtbl->ehufsi[i] = huffsize[p];
}
if(!jpeg_first_bit_table_init) {
for(i = 0; i < 65536; i++) {
int bit = 0, val = i;
while (val) {val >>= 1; bit++;}
jpeg_first_bit_table[i] = bit;
}
jpeg_first_bit_table_init = 1;
}
}
@@ -249,6 +312,8 @@ dump_buffer (working_state * state)
{
struct jpeg_destination_mgr * dest = state->cinfo->dest;
dest->free_in_buffer = state->free_in_buffer;
if (! (*dest->empty_output_buffer) (state->cinfo))
return FALSE;
/* After a successful buffer dump, must reset buffer pointers */
@@ -266,139 +331,248 @@ dump_buffer (working_state * state)
* between calls, so 24 bits are sufficient.
*/
INLINE
LOCAL(boolean)
emit_bits (working_state * state, unsigned int code, int size)
/* Emit some bits; return TRUE if successful, FALSE if must suspend */
{
/* This routine is heavily used, so it's worth coding tightly. */
register INT32 put_buffer = (INT32) code;
register int put_bits = state->cur.put_bits;
/***************************************************************/
/* if size is 0, caller used an invalid Huffman table entry */
if (size == 0)
ERREXIT(state->cinfo, JERR_HUFF_MISSING_CODE);
#define EMIT_BYTE() { \
if (0xFF == (*buffer++ = (unsigned char)(put_buffer >> (put_bits -= 8)))) \
*buffer++ = 0; \
}
put_buffer &= (((INT32) 1)<<size) - 1; /* mask off any extra bits in code */
put_bits += size; /* new number of bits in buffer */
put_buffer <<= 24 - put_bits; /* align incoming bits */
/***************************************************************/
put_buffer |= state->cur.put_buffer; /* and merge with old buffer contents */
while (put_bits >= 8) {
int c = (int) ((put_buffer >> 16) & 0xFF);
emit_byte(state, c, return FALSE);
if (c == 0xFF) { /* need to stuff a zero byte? */
emit_byte(state, 0, return FALSE);
}
put_buffer <<= 8;
put_bits -= 8;
}
#define DUMP_BITS_(code, size) { \
put_bits += size; \
put_buffer = (put_buffer << size) | code; \
if (put_bits > 7) \
while(put_bits > 7) \
EMIT_BYTE() \
}
state->cur.put_buffer = put_buffer; /* update state variables */
state->cur.put_bits = put_bits;
/***************************************************************/
return TRUE;
#define CHECKBUF15() { \
if (put_bits > 15) { \
EMIT_BYTE() \
EMIT_BYTE() \
} \
}
#define CHECKBUF47() { \
if (put_bits > 47) { \
EMIT_BYTE() \
EMIT_BYTE() \
EMIT_BYTE() \
EMIT_BYTE() \
EMIT_BYTE() \
EMIT_BYTE() \
} \
}
#define CHECKBUF31() { \
if (put_bits > 31) { \
EMIT_BYTE() \
EMIT_BYTE() \
EMIT_BYTE() \
EMIT_BYTE() \
} \
}
/***************************************************************/
#define DUMP_BITS_NOCHECK(code, size) { \
put_bits += size; \
put_buffer = (put_buffer << size) | code; \
}
#if __WORDSIZE==64 || defined(_WIN64)
#define DUMP_BITS(code, size) { \
CHECKBUF47() \
put_bits += size; \
put_buffer = (put_buffer << size) | code; \
}
#else
#define DUMP_BITS(code, size) { \
put_bits += size; \
put_buffer = (put_buffer << size) | code; \
CHECKBUF15() \
}
#endif
/***************************************************************/
#define DUMP_SINGLE_VALUE(ht, codevalue) { \
size = ht->ehufsi[codevalue]; \
code = ht->ehufco[codevalue]; \
\
DUMP_BITS(code, size) \
}
/***************************************************************/
#define DUMP_VALUE_SLOW(ht, codevalue, t, nbits) { \
size = ht->ehufsi[codevalue]; \
code = ht->ehufco[codevalue]; \
t &= ~(-1 << nbits); \
DUMP_BITS_NOCHECK(code, size) \
CHECKBUF15() \
DUMP_BITS_NOCHECK(t, nbits) \
CHECKBUF15() \
}
#if __WORDSIZE==64 || defined(_WIN64)
#define DUMP_VALUE(ht, codevalue, t, nbits) { \
size = ht->ehufsi[codevalue]; \
code = ht->ehufco[codevalue]; \
t &= ~(-1 << nbits); \
CHECKBUF31() \
DUMP_BITS_NOCHECK(code, size) \
DUMP_BITS_NOCHECK(t, nbits) \
}
#else
#define DUMP_VALUE(ht, codevalue, t, nbits) { \
size = ht->ehufsi[codevalue]; \
code = ht->ehufco[codevalue]; \
t &= ~(-1 << nbits); \
DUMP_BITS_NOCHECK(code, size) \
CHECKBUF15() \
DUMP_BITS_NOCHECK(t, nbits) \
CHECKBUF15() \
}
#endif
/***************************************************************/
#define BUFSIZE (DCTSIZE2 * 2)
#define LOAD_BUFFER() { \
if (state->free_in_buffer < BUFSIZE) { \
localbuf = 1; \
buffer = _buffer; \
} \
else buffer = state->next_output_byte; \
}
#define STORE_BUFFER() { \
if (localbuf) { \
bytes = buffer - _buffer; \
buffer = _buffer; \
while (bytes > 0) { \
bytestocopy = min(bytes, state->free_in_buffer); \
MEMCOPY(state->next_output_byte, buffer, bytestocopy); \
state->next_output_byte += bytestocopy; \
buffer += bytestocopy; \
state->free_in_buffer -= bytestocopy; \
if (state->free_in_buffer == 0) \
if (! dump_buffer(state)) return FALSE; \
bytes -= bytestocopy; \
} \
} \
else { \
state->free_in_buffer -= (buffer - state->next_output_byte); \
state->next_output_byte = buffer; \
} \
}
/***************************************************************/
LOCAL(boolean)
flush_bits (working_state * state)
{
if (! emit_bits(state, 0x7F, 7)) /* fill any partial byte with ones */
return FALSE;
unsigned char _buffer[BUFSIZE], *buffer;
size_t put_buffer; int put_bits;
size_t bytes, bytestocopy; int localbuf = 0;
put_buffer = state->cur.put_buffer;
put_bits = state->cur.put_bits;
LOAD_BUFFER()
DUMP_BITS_(0x7F, 7)
state->cur.put_buffer = 0; /* and reset bit-buffer to empty */
state->cur.put_bits = 0;
STORE_BUFFER()
return TRUE;
}
/* Encode a single block's worth of coefficients */
LOCAL(boolean)
encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val,
c_derived_tbl *dctbl, c_derived_tbl *actbl)
{
register int temp, temp2;
register int nbits;
register int k, r, i;
int temp, temp2;
int nbits;
int r, sflag, size, code;
unsigned char _buffer[BUFSIZE], *buffer;
size_t put_buffer; int put_bits;
int code_0xf0 = actbl->ehufco[0xf0], size_0xf0 = actbl->ehufsi[0xf0];
size_t bytes, bytestocopy; int localbuf = 0;
put_buffer = state->cur.put_buffer;
put_bits = state->cur.put_bits;
LOAD_BUFFER()
/* Encode the DC coefficient difference per section F.1.2.1 */
temp = temp2 = block[0] - last_dc_val;
if (temp < 0) {
temp = -temp; /* temp is abs value of input */
/* For a negative input, want temp2 = bitwise complement of abs(input) */
/* This code assumes we are on a two's complement machine */
temp2--;
}
/* Find the number of bits needed for the magnitude of the coefficient */
nbits = 0;
while (temp) {
nbits++;
temp >>= 1;
}
/* Emit the Huffman-coded symbol for the number of bits */
if (! emit_bits(state, dctbl->ehufco[nbits], dctbl->ehufsi[nbits]))
return FALSE;
/* Emit that number of bits of the value, if positive, */
/* or the complement of its magnitude, if negative. */
if (nbits) /* emit_bits rejects calls with size 0 */
if (! emit_bits(state, (unsigned int) temp2, nbits))
return FALSE;
sflag = temp >> 31;
temp -= ((temp + temp) & sflag);
temp2 += sflag;
nbits = jpeg_first_bit_table[temp];
DUMP_VALUE_SLOW(dctbl, nbits, temp2, nbits)
/* Encode the AC coefficients per section F.1.2.2 */
r = 0; /* r = run length of zeros */
for (k = 1; k < DCTSIZE2; k++) {
if ((temp = block[jpeg_natural_order[k]]) == 0) {
r++;
} else {
/* if run length > 15, must emit special run-length-16 codes (0xF0) */
while (r > 15) {
if (! emit_bits(state, actbl->ehufco[0xF0], actbl->ehufsi[0xF0]))
return FALSE;
r -= 16;
}
temp2 = temp;
if (temp < 0) {
temp = -temp; /* temp is abs value of input */
/* This code assumes we are on a two's complement machine */
temp2--;
}
/* Find the number of bits needed for the magnitude of the coefficient */
nbits = 1; /* there must be at least one 1 bit */
while ((temp >>= 1))
nbits++;
/* Emit Huffman symbol for run length / number of bits */
i = (r << 4) + nbits;
if (! emit_bits(state, actbl->ehufco[i], actbl->ehufsi[i]))
return FALSE;
#define innerloop(order) { \
temp2 = *(JCOEF*)((unsigned char*)block + order); \
if(temp2 == 0) r++; \
else { \
temp = (JCOEF)temp2; \
sflag = temp >> 31; \
temp = (temp ^ sflag) - sflag; \
temp2 += sflag; \
nbits = jpeg_first_bit_table[temp]; \
for(; r > 15; r -= 16) DUMP_BITS(code_0xf0, size_0xf0) \
sflag = (r << 4) + nbits; \
DUMP_VALUE(actbl, sflag, temp2, nbits) \
r = 0; \
}}
/* Emit that number of bits of the value, if positive, */
/* or the complement of its magnitude, if negative. */
if (! emit_bits(state, (unsigned int) temp2, nbits))
return FALSE;
r = 0;
}
}
innerloop(2*1); innerloop(2*8); innerloop(2*16); innerloop(2*9);
innerloop(2*2); innerloop(2*3); innerloop(2*10); innerloop(2*17);
innerloop(2*24); innerloop(2*32); innerloop(2*25); innerloop(2*18);
innerloop(2*11); innerloop(2*4); innerloop(2*5); innerloop(2*12);
innerloop(2*19); innerloop(2*26); innerloop(2*33); innerloop(2*40);
innerloop(2*48); innerloop(2*41); innerloop(2*34); innerloop(2*27);
innerloop(2*20); innerloop(2*13); innerloop(2*6); innerloop(2*7);
innerloop(2*14); innerloop(2*21); innerloop(2*28); innerloop(2*35);
innerloop(2*42); innerloop(2*49); innerloop(2*56); innerloop(2*57);
innerloop(2*50); innerloop(2*43); innerloop(2*36); innerloop(2*29);
innerloop(2*22); innerloop(2*15); innerloop(2*23); innerloop(2*30);
innerloop(2*37); innerloop(2*44); innerloop(2*51); innerloop(2*58);
innerloop(2*59); innerloop(2*52); innerloop(2*45); innerloop(2*38);
innerloop(2*31); innerloop(2*39); innerloop(2*46); innerloop(2*53);
innerloop(2*60); innerloop(2*61); innerloop(2*54); innerloop(2*47);
innerloop(2*55); innerloop(2*62); innerloop(2*63);
/* If the last coef(s) were zero, emit an end-of-block code */
if (r > 0)
if (! emit_bits(state, actbl->ehufco[0], actbl->ehufsi[0]))
return FALSE;
if (r > 0) DUMP_SINGLE_VALUE(actbl, 0x0)
state->cur.put_buffer = put_buffer;
state->cur.put_bits = put_bits;
STORE_BUFFER()
return TRUE;
}
@@ -516,19 +690,12 @@ finish_pass_huff (j_compress_ptr cinfo)
/*
* Huffman coding optimization.
*
* This actually is optimization, in the sense that we find the best possible
* Huffman table(s) for the given data. We first scan the supplied data and
* count the number of uses of each symbol that is to be Huffman-coded.
* (This process must agree with the code above.) Then we build an
* optimal Huffman coding tree for the observed counts.
*
* The JPEG standard requires Huffman codes to be no more than 16 bits long.
* If some symbols have a very small but nonzero probability, the Huffman tree
* must be adjusted to meet the code length restriction. We currently use
* the adjustment method suggested in the JPEG spec. This method is *not*
* optimal; it may not choose the best possible limited-length code. But
* since the symbols involved are infrequently used, it's not clear that
* going to extra trouble is worthwhile.
* We first scan the supplied data and count the number of uses of each symbol
* that is to be Huffman-coded. (This process MUST agree with the code above.)
* Then we build a Huffman coding tree for the observed counts.
* Symbols which are not needed at all for the particular image are not
* assigned any code, which saves space in the DHT marker as well as in
* the compressed data.
*/
#ifdef ENTROPY_OPT_SUPPORTED
@@ -537,7 +704,7 @@ finish_pass_huff (j_compress_ptr cinfo)
/* Process a single block's worth of coefficients */
LOCAL(void)
htest_one_block (JCOEFPTR block, int last_dc_val,
htest_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val,
long dc_counts[], long ac_counts[])
{
register int temp;
@@ -556,6 +723,11 @@ htest_one_block (JCOEFPTR block, int last_dc_val,
nbits++;
temp >>= 1;
}
/* Check for out-of-range coefficient values.
* Since we're encoding a difference, the range limit is twice as much.
*/
if (nbits > MAX_COEF_BITS+1)
ERREXIT(cinfo, JERR_BAD_DCT_COEF);
/* Count the Huffman symbol for the number of bits */
dc_counts[nbits]++;
@@ -582,6 +754,9 @@ htest_one_block (JCOEFPTR block, int last_dc_val,
nbits = 1; /* there must be at least one 1 bit */
while ((temp >>= 1))
nbits++;
/* Check for out-of-range coefficient values */
if (nbits > MAX_COEF_BITS)
ERREXIT(cinfo, JERR_BAD_DCT_COEF);
/* Count Huffman symbol for run length / number of bits */
ac_counts[(r << 4) + nbits]++;
@@ -623,7 +798,7 @@ encode_mcu_gather (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
ci = cinfo->MCU_membership[blkn];
compptr = cinfo->cur_comp_info[ci];
htest_one_block(MCU_data[blkn][0], entropy->saved.last_dc_val[ci],
htest_one_block(cinfo, MCU_data[blkn][0], entropy->saved.last_dc_val[ci],
entropy->dc_count_ptrs[compptr->dc_tbl_no],
entropy->ac_count_ptrs[compptr->ac_tbl_no]);
entropy->saved.last_dc_val[ci] = MCU_data[blkn][0][0];
@@ -634,8 +809,31 @@ encode_mcu_gather (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
/*
* Generate the optimal coding for the given counts, fill htbl.
* Generate the best Huffman code table for the given counts, fill htbl.
* Note this is also used by jcphuff.c.
*
* The JPEG standard requires that no symbol be assigned a codeword of all
* one bits (so that padding bits added at the end of a compressed segment
* can't look like a valid code). Because of the canonical ordering of
* codewords, this just means that there must be an unused slot in the
* longest codeword length category. Section K.2 of the JPEG spec suggests
* reserving such a slot by pretending that symbol 256 is a valid symbol
* with count 1. In theory that's not optimal; giving it count zero but
* including it in the symbol set anyway should give a better Huffman code.
* But the theoretically better code actually seems to come out worse in
* practice, because it produces more all-ones bytes (which incur stuffed
* zero bytes in the final file). In any case the difference is tiny.
*
* The JPEG standard requires Huffman codes to be no more than 16 bits long.
* If some symbols have a very small but nonzero probability, the Huffman tree
* must be adjusted to meet the code length restriction. We currently use
* the adjustment method suggested in JPEG section K.2. This method is *not*
* optimal; it may not choose the best possible limited-length code. But
* typically only very-low-frequency symbols will be given less-than-optimal
* lengths, so the code is almost optimal. Experimental comparisons against
* an optimal limited-length-code algorithm indicate that the difference is
* microscopic --- usually less than a hundredth of a percent of total size.
* So the extra complexity of an optimal algorithm doesn't seem worthwhile.
*/
GLOBAL(void)
@@ -656,10 +854,10 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])
for (i = 0; i < 257; i++)
others[i] = -1; /* init links to empty */
freq[256] = 1; /* make sure there is a nonzero count */
freq[256] = 1; /* make sure 256 has a nonzero count */
/* Including the pseudo-symbol 256 in the Huffman procedure guarantees
* that no real symbol is given code-value of all ones, because 256
* will be placed in the largest codeword category.
* will be placed last in the largest codeword category.
*/
/* Huffman's basic algorithm to assign optimal code lengths to symbols */

View File

@@ -1,7 +1,7 @@
/*
* jchuff.h
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Copyright (C) 1991-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -10,6 +10,18 @@
* progressive encoder (jcphuff.c). No other modules need to see these.
*/
/* The legal range of a DCT coefficient is
* -1024 .. +1023 for 8-bit data;
* -16384 .. +16383 for 12-bit data.
* Hence the magnitude should always fit in 10 or 14 bits respectively.
*/
#if BITS_IN_JSAMPLE == 8
#define MAX_COEF_BITS 10
#else
#define MAX_COEF_BITS 14
#endif
/* Derived data constructed for each Huffman table */
typedef struct {
@@ -27,7 +39,8 @@ typedef struct {
/* Expand a Huffman table definition into the derived format */
EXTERN(void) jpeg_make_c_derived_tbl
JPP((j_compress_ptr cinfo, JHUFF_TBL * htbl, c_derived_tbl ** pdtbl));
JPP((j_compress_ptr cinfo, boolean isDC, int tblno,
c_derived_tbl ** pdtbl));
/* Generate an optimal table definition given the specified counts */
EXTERN(void) jpeg_gen_optimal_table

View File

@@ -1,7 +1,7 @@
/*
* jcinit.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Copyright (C) 1991-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -42,7 +42,11 @@ jinit_compress_master (j_compress_ptr cinfo)
jinit_forward_dct(cinfo);
/* Entropy encoding: either Huffman or arithmetic coding. */
if (cinfo->arith_code) {
#ifdef C_ARITH_CODING_SUPPORTED
jinit_arith_encoder(cinfo);
#else
ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
#endif
} else {
if (cinfo->progressive_mode) {
#ifdef C_PROGRESSIVE_SUPPORTED
@@ -56,7 +60,7 @@ jinit_compress_master (j_compress_ptr cinfo)
/* Need a full-image coefficient buffer in any multi-pass mode. */
jinit_c_coef_controller(cinfo,
(cinfo->num_scans > 1 || cinfo->optimize_coding));
(boolean) (cinfo->num_scans > 1 || cinfo->optimize_coding));
jinit_c_main_controller(cinfo, FALSE /* never need full buffer here */);
jinit_marker_writer(cinfo);

View File

@@ -1,7 +1,8 @@
/*
* jcmarker.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Copyright (C) 1991-1998, Thomas G. Lane.
* Copyright (C) 2010, 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.
*
@@ -11,6 +12,7 @@
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jpegcomp.h"
typedef enum { /* JPEG marker codes */
@@ -81,6 +83,17 @@ typedef enum { /* JPEG marker codes */
} JPEG_MARKER;
/* Private state */
typedef struct {
struct jpeg_marker_writer pub; /* public fields */
unsigned int last_restart_interval; /* last DRI value emitted; 0 after SOI */
} my_marker_writer;
typedef my_marker_writer * my_marker_ptr;
/*
* Basic output routines.
*
@@ -158,8 +171,8 @@ emit_dqt (j_compress_ptr cinfo, int index)
/* The table entries must be emitted in zigzag order. */
unsigned int qval = qtbl->quantval[jpeg_natural_order[i]];
if (prec)
emit_byte(cinfo, qval >> 8);
emit_byte(cinfo, qval & 0xFF);
emit_byte(cinfo, (int) (qval >> 8));
emit_byte(cinfo, (int) (qval & 0xFF));
}
qtbl->sent_table = TRUE;
@@ -274,13 +287,13 @@ emit_sof (j_compress_ptr cinfo, JPEG_MARKER code)
emit_2bytes(cinfo, 3 * cinfo->num_components + 2 + 5 + 1); /* length */
/* Make sure image isn't bigger than SOF field can handle */
if ((long) cinfo->image_height > 65535L ||
(long) cinfo->image_width > 65535L)
if ((long) cinfo->_jpeg_height > 65535L ||
(long) cinfo->_jpeg_width > 65535L)
ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) 65535);
emit_byte(cinfo, cinfo->data_precision);
emit_2bytes(cinfo, (int) cinfo->image_height);
emit_2bytes(cinfo, (int) cinfo->image_width);
emit_2bytes(cinfo, (int) cinfo->_jpeg_height);
emit_2bytes(cinfo, (int) cinfo->_jpeg_width);
emit_byte(cinfo, cinfo->num_components);
@@ -342,7 +355,7 @@ emit_jfif_app0 (j_compress_ptr cinfo)
* Length of APP0 block (2 bytes)
* Block ID (4 bytes - ASCII "JFIF")
* Zero byte (1 byte to terminate the ID string)
* Version Major, Minor (2 bytes - 0x01, 0x01)
* Version Major, Minor (2 bytes - major first)
* Units (1 byte - 0x00 = none, 0x01 = inch, 0x02 = cm)
* Xdpu (2 bytes - dots per unit horizontal)
* Ydpu (2 bytes - dots per unit vertical)
@@ -359,11 +372,8 @@ emit_jfif_app0 (j_compress_ptr cinfo)
emit_byte(cinfo, 0x49);
emit_byte(cinfo, 0x46);
emit_byte(cinfo, 0);
/* We currently emit version code 1.01 since we use no 1.02 features.
* This may avoid complaints from some older decoders.
*/
emit_byte(cinfo, 1); /* Major version */
emit_byte(cinfo, 1); /* Minor version */
emit_byte(cinfo, cinfo->JFIF_major_version); /* Version fields */
emit_byte(cinfo, cinfo->JFIF_minor_version);
emit_byte(cinfo, cinfo->density_unit); /* Pixel size information */
emit_2bytes(cinfo, (int) cinfo->X_density);
emit_2bytes(cinfo, (int) cinfo->Y_density);
@@ -419,28 +429,30 @@ emit_adobe_app14 (j_compress_ptr cinfo)
/*
* This routine is exported for possible use by applications.
* The intended use is to emit COM or APPn markers after calling
* jpeg_start_compress() and before the first jpeg_write_scanlines() call
* (hence, after write_file_header but before write_frame_header).
* These routines allow writing an arbitrary marker with parameters.
* The only intended use is to emit COM or APPn markers after calling
* write_file_header and before calling write_frame_header.
* Other uses are not guaranteed to produce desirable results.
* Counting the parameter bytes properly is the caller's responsibility.
*/
METHODDEF(void)
write_any_marker (j_compress_ptr cinfo, int marker,
const JOCTET *dataptr, unsigned int datalen)
/* Emit an arbitrary marker with parameters */
write_marker_header (j_compress_ptr cinfo, int marker, unsigned int datalen)
/* Emit an arbitrary marker header */
{
if (datalen <= (unsigned int) 65533) { /* safety check */
emit_marker(cinfo, (JPEG_MARKER) marker);
emit_2bytes(cinfo, (int) (datalen + 2)); /* total length */
if (datalen > (unsigned int) 65533) /* safety check */
ERREXIT(cinfo, JERR_BAD_LENGTH);
while (datalen--) {
emit_byte(cinfo, *dataptr);
dataptr++;
}
}
emit_marker(cinfo, (JPEG_MARKER) marker);
emit_2bytes(cinfo, (int) (datalen + 2)); /* total length */
}
METHODDEF(void)
write_marker_byte (j_compress_ptr cinfo, int val)
/* Emit one byte of marker parameters following write_marker_header */
{
emit_byte(cinfo, val);
}
@@ -458,8 +470,13 @@ write_any_marker (j_compress_ptr cinfo, int marker,
METHODDEF(void)
write_file_header (j_compress_ptr cinfo)
{
my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
emit_marker(cinfo, M_SOI); /* first the SOI */
/* SOI is defined to reset restart interval to 0 */
marker->last_restart_interval = 0;
if (cinfo->write_JFIF_header) /* next an optional JFIF APP0 */
emit_jfif_app0(cinfo);
if (cinfo->write_Adobe_marker) /* next an optional Adobe APP14 */
@@ -535,6 +552,7 @@ write_frame_header (j_compress_ptr cinfo)
METHODDEF(void)
write_scan_header (j_compress_ptr cinfo)
{
my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
int i;
jpeg_component_info *compptr;
@@ -567,11 +585,12 @@ write_scan_header (j_compress_ptr cinfo)
}
/* Emit DRI if required --- note that DRI value could change for each scan.
* If it doesn't, a tiny amount of space is wasted in multiple-scan files.
* We assume DRI will never be nonzero for one scan and zero for a later one.
* We avoid wasting space with unnecessary DRIs, however.
*/
if (cinfo->restart_interval)
if (cinfo->restart_interval != marker->last_restart_interval) {
emit_dri(cinfo);
marker->last_restart_interval = cinfo->restart_interval;
}
emit_sos(cinfo);
}
@@ -627,15 +646,21 @@ write_tables_only (j_compress_ptr cinfo)
GLOBAL(void)
jinit_marker_writer (j_compress_ptr cinfo)
{
my_marker_ptr marker;
/* Create the subobject */
cinfo->marker = (struct jpeg_marker_writer *)
marker = (my_marker_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(struct jpeg_marker_writer));
SIZEOF(my_marker_writer));
cinfo->marker = (struct jpeg_marker_writer *) marker;
/* Initialize method pointers */
cinfo->marker->write_any_marker = write_any_marker;
cinfo->marker->write_file_header = write_file_header;
cinfo->marker->write_frame_header = write_frame_header;
cinfo->marker->write_scan_header = write_scan_header;
cinfo->marker->write_file_trailer = write_file_trailer;
cinfo->marker->write_tables_only = write_tables_only;
marker->pub.write_file_header = write_file_header;
marker->pub.write_frame_header = write_frame_header;
marker->pub.write_scan_header = write_scan_header;
marker->pub.write_file_trailer = write_file_trailer;
marker->pub.write_tables_only = write_tables_only;
marker->pub.write_marker_header = write_marker_header;
marker->pub.write_marker_byte = write_marker_byte;
/* Initialize private state */
marker->last_restart_interval = 0;
}

View File

@@ -1,7 +1,9 @@
/*
* jcmaster.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2003-2010 by Guido Vollbeding.
* Copyright (C) 2010, 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.
*
@@ -14,6 +16,7 @@
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jpegcomp.h"
/* Private state */
@@ -42,8 +45,28 @@ typedef my_comp_master * my_master_ptr;
* Support routines that do various essential calculations.
*/
#if JPEG_LIB_VERSION >= 70
/*
* Compute JPEG image dimensions and related values.
* NOTE: this is exported for possible use by application.
* Hence it mustn't do anything that can't be done twice.
*/
GLOBAL(void)
jpeg_calc_jpeg_dimensions (j_compress_ptr cinfo)
/* Do computations that are needed before master selection phase */
{
/* Hardwire it to "no scaling" */
cinfo->jpeg_width = cinfo->image_width;
cinfo->jpeg_height = cinfo->image_height;
cinfo->min_DCT_h_scaled_size = DCTSIZE;
cinfo->min_DCT_v_scaled_size = DCTSIZE;
}
#endif
LOCAL(void)
initial_setup (j_compress_ptr cinfo)
initial_setup (j_compress_ptr cinfo, boolean transcode_only)
/* Do computations that are needed before master selection phase */
{
int ci;
@@ -51,14 +74,19 @@ initial_setup (j_compress_ptr cinfo)
long samplesperrow;
JDIMENSION jd_samplesperrow;
#if JPEG_LIB_VERSION >= 70
if (!transcode_only)
jpeg_calc_jpeg_dimensions(cinfo);
#endif
/* Sanity check on image dimensions */
if (cinfo->image_height <= 0 || cinfo->image_width <= 0
if (cinfo->_jpeg_height <= 0 || cinfo->_jpeg_width <= 0
|| cinfo->num_components <= 0 || cinfo->input_components <= 0)
ERREXIT(cinfo, JERR_EMPTY_IMAGE);
/* Make sure image isn't bigger than I can handle */
if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION ||
(long) cinfo->image_width > (long) JPEG_MAX_DIMENSION)
if ((long) cinfo->_jpeg_height > (long) JPEG_MAX_DIMENSION ||
(long) cinfo->_jpeg_width > (long) JPEG_MAX_DIMENSION)
ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION);
/* Width of an input scanline must be representable as JDIMENSION. */
@@ -96,20 +124,24 @@ initial_setup (j_compress_ptr cinfo)
/* Fill in the correct component_index value; don't rely on application */
compptr->component_index = ci;
/* For compression, we never do DCT scaling. */
#if JPEG_LIB_VERSION >= 70
compptr->DCT_h_scaled_size = compptr->DCT_v_scaled_size = DCTSIZE;
#else
compptr->DCT_scaled_size = DCTSIZE;
#endif
/* Size in DCT blocks */
compptr->width_in_blocks = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
jdiv_round_up((long) cinfo->_jpeg_width * (long) compptr->h_samp_factor,
(long) (cinfo->max_h_samp_factor * DCTSIZE));
compptr->height_in_blocks = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
jdiv_round_up((long) cinfo->_jpeg_height * (long) compptr->v_samp_factor,
(long) (cinfo->max_v_samp_factor * DCTSIZE));
/* Size in samples */
compptr->downsampled_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
jdiv_round_up((long) cinfo->_jpeg_width * (long) compptr->h_samp_factor,
(long) cinfo->max_h_samp_factor);
compptr->downsampled_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
jdiv_round_up((long) cinfo->_jpeg_height * (long) compptr->v_samp_factor,
(long) cinfo->max_v_samp_factor);
/* Mark component needed (this flag isn't actually used for compression) */
compptr->component_needed = TRUE;
@@ -119,7 +151,7 @@ initial_setup (j_compress_ptr cinfo)
* main controller will call coefficient controller).
*/
cinfo->total_iMCU_rows = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height,
jdiv_round_up((long) cinfo->_jpeg_height,
(long) (cinfo->max_v_samp_factor*DCTSIZE));
}
@@ -185,8 +217,20 @@ validate_script (j_compress_ptr cinfo)
Al = scanptr->Al;
if (cinfo->progressive_mode) {
#ifdef C_PROGRESSIVE_SUPPORTED
/* The JPEG spec simply gives the ranges 0..13 for Ah and Al, but that
* seems wrong: the upper bound ought to depend on data precision.
* Perhaps they really meant 0..N+1 for N-bit precision.
* Here we allow 0..10 for 8-bit data; Al larger than 10 results in
* out-of-range reconstructed DC values during the first DC scan,
* which might cause problems for some decoders.
*/
#if BITS_IN_JSAMPLE == 8
#define MAX_AH_AL 10
#else
#define MAX_AH_AL 13
#endif
if (Ss < 0 || Ss >= DCTSIZE2 || Se < Ss || Se >= DCTSIZE2 ||
Ah < 0 || Ah > 13 || Al < 0 || Al > 13)
Ah < 0 || Ah > MAX_AH_AL || Al < 0 || Al > MAX_AH_AL)
ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
if (Ss == 0) {
if (Se != 0) /* DC and AC together not OK */
@@ -335,10 +379,10 @@ per_scan_setup (j_compress_ptr cinfo)
/* Overall image size in MCUs */
cinfo->MCUs_per_row = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width,
jdiv_round_up((long) cinfo->_jpeg_width,
(long) (cinfo->max_h_samp_factor*DCTSIZE));
cinfo->MCU_rows_in_scan = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height,
jdiv_round_up((long) cinfo->_jpeg_height,
(long) (cinfo->max_v_samp_factor*DCTSIZE));
cinfo->blocks_in_MCU = 0;
@@ -542,7 +586,7 @@ jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only)
master->pub.is_last_pass = FALSE;
/* Validate parameters, determine derived values */
initial_setup(cinfo);
initial_setup(cinfo, transcode_only);
if (cinfo->scan_info != NULL) {
#ifdef C_MULTISCAN_FILES_SUPPORTED

View File

@@ -1,7 +1,7 @@
/*
* jcomapi.c
*
* Copyright (C) 1994-1996, Thomas G. Lane.
* Copyright (C) 1994-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -30,6 +30,10 @@ jpeg_abort (j_common_ptr cinfo)
{
int pool;
/* Do nothing if called on a not-initialized or destroyed JPEG object. */
if (cinfo->mem == NULL)
return;
/* Releasing pools in reverse order might help avoid fragmentation
* with some (brain-damaged) malloc libraries.
*/
@@ -38,7 +42,15 @@ jpeg_abort (j_common_ptr cinfo)
}
/* Reset overall state for possible reuse of object */
cinfo->global_state = (cinfo->is_decompressor ? DSTATE_START : CSTATE_START);
if (cinfo->is_decompressor) {
cinfo->global_state = DSTATE_START;
/* Try to keep application from accessing now-deleted marker list.
* A bit kludgy to do it here, but this is the most central place.
*/
((j_decompress_ptr) cinfo)->marker_list = NULL;
} else {
cinfo->global_state = CSTATE_START;
}
}

View File

@@ -1,48 +0,0 @@
/* jconfig.bcc --- jconfig.h for Borland C (Turbo C) on MS-DOS or OS/2. */
/* see jconfig.doc for explanations */
#define HAVE_PROTOTYPES
#define HAVE_UNSIGNED_CHAR
#define HAVE_UNSIGNED_SHORT
/* #define void char */
/* #define const */
#undef CHAR_IS_UNSIGNED
#define HAVE_STDDEF_H
#define HAVE_STDLIB_H
#undef NEED_BSD_STRINGS
#undef NEED_SYS_TYPES_H
#ifdef __MSDOS__
#define NEED_FAR_POINTERS /* for small or medium memory model */
#endif
#undef NEED_SHORT_EXTERNAL_NAMES
#undef INCOMPLETE_TYPES_BROKEN /* this assumes you have -w-stu in CFLAGS */
#ifdef JPEG_INTERNALS
#undef RIGHT_SHIFT_IS_UNSIGNED
#ifdef __MSDOS__
#define USE_MSDOS_MEMMGR /* Define this if you use jmemdos.c */
#define MAX_ALLOC_CHUNK 65520L /* Maximum request to malloc() */
#define USE_FMEM /* Borland has _fmemcpy() and _fmemset() */
#endif
#endif /* JPEG_INTERNALS */
#ifdef JPEG_CJPEG_DJPEG
#define BMP_SUPPORTED /* BMP image file format */
#define GIF_SUPPORTED /* GIF image file format */
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
#undef RLE_SUPPORTED /* Utah RLE image file format */
#define TARGA_SUPPORTED /* Targa image file format */
#define TWO_FILE_COMMANDLINE
#define USE_SETMODE /* Borland has setmode() */
#ifdef __MSDOS__
#define NEED_SIGNAL_CATCHER /* Define this if you use jmemdos.c */
#endif
#undef DONT_USE_B_MODE
#undef PROGRESS_REPORT /* optional */
#endif /* JPEG_CJPEG_DJPEG */

View File

@@ -1,44 +0,0 @@
/* jconfig.cfg --- source file edited by configure script */
/* see jconfig.doc for explanations */
#undef HAVE_PROTOTYPES
#undef HAVE_UNSIGNED_CHAR
#undef HAVE_UNSIGNED_SHORT
#undef void
#undef const
#undef CHAR_IS_UNSIGNED
#undef HAVE_STDDEF_H
#undef HAVE_STDLIB_H
#undef NEED_BSD_STRINGS
#undef NEED_SYS_TYPES_H
#undef NEED_FAR_POINTERS
#undef NEED_SHORT_EXTERNAL_NAMES
/* Define this if you get warnings about undefined structures. */
#undef INCOMPLETE_TYPES_BROKEN
#ifdef JPEG_INTERNALS
#undef RIGHT_SHIFT_IS_UNSIGNED
#undef INLINE
/* These are for configuring the JPEG memory manager. */
#undef DEFAULT_MAX_MEM
#undef NO_MKTEMP
#endif /* JPEG_INTERNALS */
#ifdef JPEG_CJPEG_DJPEG
#define BMP_SUPPORTED /* BMP image file format */
#define GIF_SUPPORTED /* GIF image file format */
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
#undef RLE_SUPPORTED /* Utah RLE image file format */
#define TARGA_SUPPORTED /* Targa image file format */
#undef TWO_FILE_COMMANDLINE
#undef NEED_SIGNAL_CATCHER
#undef DONT_USE_B_MODE
/* Define this if you want percent-done progress reports from cjpeg/djpeg. */
#undef PROGRESS_REPORT
#endif /* JPEG_CJPEG_DJPEG */

View File

@@ -1,38 +0,0 @@
/* jconfig.dj --- jconfig.h for DJGPP (Delorie's GNU C port) on MS-DOS. */
/* see jconfig.doc for explanations */
#define HAVE_PROTOTYPES
#define HAVE_UNSIGNED_CHAR
#define HAVE_UNSIGNED_SHORT
/* #define void char */
/* #define const */
#undef CHAR_IS_UNSIGNED
#define HAVE_STDDEF_H
#define HAVE_STDLIB_H
#undef NEED_BSD_STRINGS
#undef NEED_SYS_TYPES_H
#undef NEED_FAR_POINTERS /* DJGPP uses flat 32-bit addressing */
#undef NEED_SHORT_EXTERNAL_NAMES
#undef INCOMPLETE_TYPES_BROKEN
#ifdef JPEG_INTERNALS
#undef RIGHT_SHIFT_IS_UNSIGNED
#endif /* JPEG_INTERNALS */
#ifdef JPEG_CJPEG_DJPEG
#define BMP_SUPPORTED /* BMP image file format */
#define GIF_SUPPORTED /* GIF image file format */
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
#undef RLE_SUPPORTED /* Utah RLE image file format */
#define TARGA_SUPPORTED /* Targa image file format */
#undef TWO_FILE_COMMANDLINE /* optional */
#define USE_SETMODE /* Needed to make one-file style work in DJGPP */
#undef NEED_SIGNAL_CATCHER /* Define this if you use jmemname.c */
#undef DONT_USE_B_MODE
#undef PROGRESS_REPORT /* optional */
#endif /* JPEG_CJPEG_DJPEG */

60
jconfig.h.in Normal file
View File

@@ -0,0 +1,60 @@
/* Version ID for the JPEG library.
* Might be useful for tests like "#if JPEG_LIB_VERSION >= 60".
*/
#define JPEG_LIB_VERSION 62 /* Version 6b */
/* Support arithmetic encoding */
#undef C_ARITH_CODING_SUPPORTED
/* Support arithmetic decoding */
#undef D_ARITH_CODING_SUPPORTED
/* Define if your compiler supports prototypes */
#undef HAVE_PROTOTYPES
/* Define to 1 if you have the <stddef.h> header file. */
#undef HAVE_STDDEF_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if the system has the type `unsigned char'. */
#undef HAVE_UNSIGNED_CHAR
/* Define to 1 if the system has the type `unsigned short'. */
#undef HAVE_UNSIGNED_SHORT
/* Define if you want use complete types */
#undef INCOMPLETE_TYPES_BROKEN
/* Define if you have BSD-like bzero and bcopy */
#undef NEED_BSD_STRINGS
/* Define if you need short function names */
#undef NEED_SHORT_EXTERNAL_NAMES
/* Define if you have sys/types.h */
#undef NEED_SYS_TYPES_H
/* Define if shift is unsigned */
#undef RIGHT_SHIFT_IS_UNSIGNED
/* Use accelerated SIMD routines. */
#undef WITH_SIMD
/* Define to 1 if type `char' is unsigned and you are not using gcc. */
#ifndef __CHAR_UNSIGNED__
# undef __CHAR_UNSIGNED__
#endif
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
#undef inline
#endif
/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t

View File

@@ -1,43 +0,0 @@
/* jconfig.manx --- jconfig.h for Amiga systems using Manx Aztec C ver 5.x. */
/* see jconfig.doc for explanations */
#define HAVE_PROTOTYPES
#define HAVE_UNSIGNED_CHAR
#define HAVE_UNSIGNED_SHORT
/* #define void char */
/* #define const */
#undef CHAR_IS_UNSIGNED
#define HAVE_STDDEF_H
#define HAVE_STDLIB_H
#undef NEED_BSD_STRINGS
#undef NEED_SYS_TYPES_H
#undef NEED_FAR_POINTERS
#undef NEED_SHORT_EXTERNAL_NAMES
#undef INCOMPLETE_TYPES_BROKEN
#ifdef JPEG_INTERNALS
#undef RIGHT_SHIFT_IS_UNSIGNED
#define TEMP_DIRECTORY "JPEGTMP:" /* recommended setting for Amiga */
#define SHORTxSHORT_32 /* produces better DCT code with Aztec C */
#endif /* JPEG_INTERNALS */
#ifdef JPEG_CJPEG_DJPEG
#define BMP_SUPPORTED /* BMP image file format */
#define GIF_SUPPORTED /* GIF image file format */
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
#undef RLE_SUPPORTED /* Utah RLE image file format */
#define TARGA_SUPPORTED /* Targa image file format */
#define TWO_FILE_COMMANDLINE
#define NEED_SIGNAL_CATCHER
#undef DONT_USE_B_MODE
#undef PROGRESS_REPORT /* optional */
#define signal_catcher _abort /* hack for Aztec C naming requirements */
#endif /* JPEG_CJPEG_DJPEG */

View File

@@ -1,52 +0,0 @@
/* jconfig.mc6 --- jconfig.h for Microsoft C on MS-DOS, version 6.00A & up. */
/* see jconfig.doc for explanations */
#define HAVE_PROTOTYPES
#define HAVE_UNSIGNED_CHAR
#define HAVE_UNSIGNED_SHORT
/* #define void char */
/* #define const */
#undef CHAR_IS_UNSIGNED
#define HAVE_STDDEF_H
#define HAVE_STDLIB_H
#undef NEED_BSD_STRINGS
#undef NEED_SYS_TYPES_H
#define NEED_FAR_POINTERS /* for small or medium memory model */
#undef NEED_SHORT_EXTERNAL_NAMES
#undef INCOMPLETE_TYPES_BROKEN
#ifdef JPEG_INTERNALS
#undef RIGHT_SHIFT_IS_UNSIGNED
#define USE_MSDOS_MEMMGR /* Define this if you use jmemdos.c */
#define MAX_ALLOC_CHUNK 65520L /* Maximum request to malloc() */
#define USE_FMEM /* Microsoft has _fmemcpy() and _fmemset() */
#define NEED_FHEAPMIN /* far heap management routines are broken */
#define SHORTxLCONST_32 /* enable compiler-specific DCT optimization */
/* Note: the above define is known to improve the code with Microsoft C 6.00A.
* I do not know whether it is good for later compiler versions.
* Please report any info on this point to jpeg-info@uunet.uu.net.
*/
#endif /* JPEG_INTERNALS */
#ifdef JPEG_CJPEG_DJPEG
#define BMP_SUPPORTED /* BMP image file format */
#define GIF_SUPPORTED /* GIF image file format */
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
#undef RLE_SUPPORTED /* Utah RLE image file format */
#define TARGA_SUPPORTED /* Targa image file format */
#define TWO_FILE_COMMANDLINE
#define USE_SETMODE /* Microsoft has setmode() */
#define NEED_SIGNAL_CATCHER /* Define this if you use jmemdos.c */
#undef DONT_USE_B_MODE
#undef PROGRESS_REPORT /* optional */
#endif /* JPEG_CJPEG_DJPEG */

View File

@@ -1,43 +0,0 @@
/* jconfig.sas --- jconfig.h for Amiga systems using SAS C 6.0 and up. */
/* see jconfig.doc for explanations */
#define HAVE_PROTOTYPES
#define HAVE_UNSIGNED_CHAR
#define HAVE_UNSIGNED_SHORT
/* #define void char */
/* #define const */
#undef CHAR_IS_UNSIGNED
#define HAVE_STDDEF_H
#define HAVE_STDLIB_H
#undef NEED_BSD_STRINGS
#undef NEED_SYS_TYPES_H
#undef NEED_FAR_POINTERS
#undef NEED_SHORT_EXTERNAL_NAMES
#undef INCOMPLETE_TYPES_BROKEN
#ifdef JPEG_INTERNALS
#undef RIGHT_SHIFT_IS_UNSIGNED
#define TEMP_DIRECTORY "JPEGTMP:" /* recommended setting for Amiga */
#define NO_MKTEMP /* SAS C doesn't have mktemp() */
#define SHORTxSHORT_32 /* produces better DCT code with SAS C */
#endif /* JPEG_INTERNALS */
#ifdef JPEG_CJPEG_DJPEG
#define BMP_SUPPORTED /* BMP image file format */
#define GIF_SUPPORTED /* GIF image file format */
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
#undef RLE_SUPPORTED /* Utah RLE image file format */
#define TARGA_SUPPORTED /* Targa image file format */
#define TWO_FILE_COMMANDLINE
#define NEED_SIGNAL_CATCHER
#undef DONT_USE_B_MODE
#undef PROGRESS_REPORT /* optional */
#endif /* JPEG_CJPEG_DJPEG */

View File

@@ -1,42 +0,0 @@
/* jconfig.st --- jconfig.h for Atari ST/STE/TT using Pure C or Turbo C. */
/* see jconfig.doc for explanations */
#define HAVE_PROTOTYPES
#define HAVE_UNSIGNED_CHAR
#define HAVE_UNSIGNED_SHORT
/* #define void char */
/* #define const */
#undef CHAR_IS_UNSIGNED
#define HAVE_STDDEF_H
#define HAVE_STDLIB_H
#undef NEED_BSD_STRINGS
#undef NEED_SYS_TYPES_H
#undef NEED_FAR_POINTERS
#undef NEED_SHORT_EXTERNAL_NAMES
#define INCOMPLETE_TYPES_BROKEN /* suppress undefined-structure warnings */
#ifdef JPEG_INTERNALS
#undef RIGHT_SHIFT_IS_UNSIGNED
#define ALIGN_TYPE long /* apparently double is a weird size? */
#endif /* JPEG_INTERNALS */
#ifdef JPEG_CJPEG_DJPEG
#define BMP_SUPPORTED /* BMP image file format */
#define GIF_SUPPORTED /* GIF image file format */
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
#undef RLE_SUPPORTED /* Utah RLE image file format */
#define TARGA_SUPPORTED /* Targa image file format */
#define TWO_FILE_COMMANDLINE /* optional -- undef if you like Unix style */
/* Note: if you undef TWO_FILE_COMMANDLINE, you may need to define
* USE_SETMODE. Some Atari compilers require it, some do not.
*/
#define NEED_SIGNAL_CATCHER /* needed if you use jmemname.c */
#undef DONT_USE_B_MODE
#undef PROGRESS_REPORT /* optional */
#endif /* JPEG_CJPEG_DJPEG */

View File

@@ -1,5 +1,5 @@
/*
* jconfig.doc
* jconfig.txt
*
* Copyright (C) 1991-1994, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
@@ -24,7 +24,7 @@
*/
/* Does your compiler support function prototypes?
* (If not, you also need to use ansi2knr, see install.doc)
* (If not, you also need to use ansi2knr, see install.txt)
*/
#define HAVE_PROTOTYPES
@@ -91,6 +91,15 @@
*/
#undef INCOMPLETE_TYPES_BROKEN
/* Define "boolean" as unsigned char, not int, on Windows systems.
*/
#ifdef _WIN32
#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */
typedef unsigned char boolean;
#endif
#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */
#endif
/*
* The following options affect code selection within the JPEG library,

View File

@@ -1,37 +0,0 @@
/* jconfig.vms --- jconfig.h for use on Digital VMS. */
/* see jconfig.doc for explanations */
#define HAVE_PROTOTYPES
#define HAVE_UNSIGNED_CHAR
#define HAVE_UNSIGNED_SHORT
/* #define void char */
/* #define const */
#undef CHAR_IS_UNSIGNED
#define HAVE_STDDEF_H
#define HAVE_STDLIB_H
#undef NEED_BSD_STRINGS
#undef NEED_SYS_TYPES_H
#undef NEED_FAR_POINTERS
#undef NEED_SHORT_EXTERNAL_NAMES
#undef INCOMPLETE_TYPES_BROKEN
#ifdef JPEG_INTERNALS
#undef RIGHT_SHIFT_IS_UNSIGNED
#endif /* JPEG_INTERNALS */
#ifdef JPEG_CJPEG_DJPEG
#define BMP_SUPPORTED /* BMP image file format */
#define GIF_SUPPORTED /* GIF image file format */
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
#undef RLE_SUPPORTED /* Utah RLE image file format */
#define TARGA_SUPPORTED /* Targa image file format */
#define TWO_FILE_COMMANDLINE /* Needed on VMS */
#undef NEED_SIGNAL_CATCHER
#undef DONT_USE_B_MODE
#undef PROGRESS_REPORT /* optional */
#endif /* JPEG_CJPEG_DJPEG */

View File

@@ -1,38 +0,0 @@
/* jconfig.wat --- jconfig.h for Watcom C/C++ on MS-DOS or OS/2. */
/* see jconfig.doc for explanations */
#define HAVE_PROTOTYPES
#define HAVE_UNSIGNED_CHAR
#define HAVE_UNSIGNED_SHORT
/* #define void char */
/* #define const */
#define CHAR_IS_UNSIGNED
#define HAVE_STDDEF_H
#define HAVE_STDLIB_H
#undef NEED_BSD_STRINGS
#undef NEED_SYS_TYPES_H
#undef NEED_FAR_POINTERS /* Watcom uses flat 32-bit addressing */
#undef NEED_SHORT_EXTERNAL_NAMES
#undef INCOMPLETE_TYPES_BROKEN
#ifdef JPEG_INTERNALS
#undef RIGHT_SHIFT_IS_UNSIGNED
#endif /* JPEG_INTERNALS */
#ifdef JPEG_CJPEG_DJPEG
#define BMP_SUPPORTED /* BMP image file format */
#define GIF_SUPPORTED /* GIF image file format */
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
#undef RLE_SUPPORTED /* Utah RLE image file format */
#define TARGA_SUPPORTED /* Targa image file format */
#undef TWO_FILE_COMMANDLINE /* optional */
#define USE_SETMODE /* Needed to make one-file style work in Watcom */
#undef NEED_SIGNAL_CATCHER /* Define this if you use jmemname.c */
#undef DONT_USE_B_MODE
#undef PROGRESS_REPORT /* optional */
#endif /* JPEG_CJPEG_DJPEG */

139
jcparam.c
View File

@@ -1,7 +1,9 @@
/*
* jcparam.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Copyright (C) 1991-1998, Thomas G. Lane.
* Modified 2003-2008 by Guido Vollbeding.
* Copyright (C) 2009-2010, 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.
*
@@ -29,7 +31,7 @@ jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl,
* are limited to 1..255 for JPEG baseline compatibility.
*/
{
JQUANT_TBL ** qtblptr = & cinfo->quant_tbl_ptrs[which_tbl];
JQUANT_TBL ** qtblptr;
int i;
long temp;
@@ -37,6 +39,11 @@ jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl,
if (cinfo->global_state != CSTATE_START)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
if (which_tbl < 0 || which_tbl >= NUM_QUANT_TBLS)
ERREXIT1(cinfo, JERR_DQT_INDEX, which_tbl);
qtblptr = & cinfo->quant_tbl_ptrs[which_tbl];
if (*qtblptr == NULL)
*qtblptr = jpeg_alloc_quant_table((j_common_ptr) cinfo);
@@ -55,6 +62,49 @@ jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl,
}
/* These are the sample quantization tables given in JPEG spec section K.1.
* The spec says that the values given produce "good" quality, and
* when divided by 2, "very good" quality.
*/
static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = {
16, 11, 10, 16, 24, 40, 51, 61,
12, 12, 14, 19, 26, 58, 60, 55,
14, 13, 16, 24, 40, 57, 69, 56,
14, 17, 22, 29, 51, 87, 80, 62,
18, 22, 37, 56, 68, 109, 103, 77,
24, 35, 55, 64, 81, 104, 113, 92,
49, 64, 78, 87, 103, 121, 120, 101,
72, 92, 95, 98, 112, 100, 103, 99
};
static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = {
17, 18, 24, 47, 99, 99, 99, 99,
18, 21, 26, 66, 99, 99, 99, 99,
24, 26, 56, 99, 99, 99, 99, 99,
47, 66, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99
};
#if JPEG_LIB_VERSION >= 70
GLOBAL(void)
jpeg_default_qtables (j_compress_ptr cinfo, boolean force_baseline)
/* Set or change the 'quality' (quantization) setting, using default tables
* and straight percentage-scaling quality scales.
* This entry point allows different scalings for luminance and chrominance.
*/
{
/* Set up two quantization tables using the specified scaling */
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
GLOBAL(void)
jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor,
boolean force_baseline)
@@ -64,31 +114,6 @@ jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor,
* applications that insist on a linear percentage scaling.
*/
{
/* These are the sample quantization tables given in JPEG spec section K.1.
* The spec says that the values given produce "good" quality, and
* when divided by 2, "very good" quality.
*/
static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = {
16, 11, 10, 16, 24, 40, 51, 61,
12, 12, 14, 19, 26, 58, 60, 55,
14, 13, 16, 24, 40, 57, 69, 56,
14, 17, 22, 29, 51, 87, 80, 62,
18, 22, 37, 56, 68, 109, 103, 77,
24, 35, 55, 64, 81, 104, 113, 92,
49, 64, 78, 87, 103, 121, 120, 101,
72, 92, 95, 98, 112, 100, 103, 99
};
static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = {
17, 18, 24, 47, 99, 99, 99, 99,
18, 21, 26, 66, 99, 99, 99, 99,
24, 26, 56, 99, 99, 99, 99, 99,
47, 66, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99
};
/* Set up two quantization tables using the specified scaling */
jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl,
scale_factor, force_baseline);
@@ -148,11 +173,25 @@ add_huff_table (j_compress_ptr cinfo,
JHUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val)
/* Define a Huffman table */
{
int nsymbols, len;
if (*htblptr == NULL)
*htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
/* Copy the number-of-symbols-of-each-code-length counts */
MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits));
MEMCOPY((*htblptr)->huffval, val, SIZEOF((*htblptr)->huffval));
/* Validate the counts. We do this here mainly so we can copy the right
* number of symbols from the val[] array, without risking marching off
* the end of memory. jchuff.c will do a more thorough test later.
*/
nsymbols = 0;
for (len = 1; len <= 16; len++)
nsymbols += bits[len];
if (nsymbols < 1 || nsymbols > 256)
ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
MEMCOPY((*htblptr)->huffval, val, nsymbols * SIZEOF(UINT8));
/* Initialize sent_table FALSE so table will be written to JPEG file. */
(*htblptr)->sent_table = FALSE;
@@ -265,6 +304,10 @@ jpeg_set_defaults (j_compress_ptr cinfo)
/* Initialize everything not dependent on the color space */
#if JPEG_LIB_VERSION >= 70
cinfo->scale_num = 1; /* 1:1 scaling */
cinfo->scale_denom = 1;
#endif
cinfo->data_precision = BITS_IN_JSAMPLE;
/* Set up two quantization tables using default quality of 75 */
jpeg_set_quality(cinfo, 75, TRUE);
@@ -301,6 +344,11 @@ jpeg_set_defaults (j_compress_ptr cinfo)
/* By default, use the simpler non-cosited sampling alignment */
cinfo->CCIR601_sampling = FALSE;
#if JPEG_LIB_VERSION >= 70
/* By default, apply fancy downsampling */
cinfo->do_fancy_downsampling = TRUE;
#endif
/* No input smoothing */
cinfo->smoothing_factor = 0;
@@ -313,7 +361,15 @@ jpeg_set_defaults (j_compress_ptr cinfo)
/* Fill in default JFIF marker parameters. Note that whether the marker
* will actually be written is determined by jpeg_set_colorspace.
*
* By default, the library emits JFIF version code 1.01.
* An application that wants to emit JFIF 1.02 extension markers should set
* JFIF_minor_version to 2. We could probably get away with just defaulting
* to 1.02, but there may still be some decoders in use that will complain
* about that; saying 1.01 should minimize compatibility problems.
*/
cinfo->JFIF_major_version = 1; /* Default JFIF version = 1.01 */
cinfo->JFIF_minor_version = 1;
cinfo->density_unit = 0; /* Pixel size is unknown by default */
cinfo->X_density = 1; /* Pixel aspect ratio is square by default */
cinfo->Y_density = 1;
@@ -336,6 +392,12 @@ jpeg_default_colorspace (j_compress_ptr cinfo)
jpeg_set_colorspace(cinfo, JCS_GRAYSCALE);
break;
case JCS_RGB:
case JCS_EXT_RGB:
case JCS_EXT_RGBX:
case JCS_EXT_BGR:
case JCS_EXT_BGRX:
case JCS_EXT_XBGR:
case JCS_EXT_XRGB:
jpeg_set_colorspace(cinfo, JCS_YCbCr);
break;
case JCS_YCbCr:
@@ -529,11 +591,20 @@ jpeg_simple_progression (j_compress_ptr cinfo)
nscans = 2 + 4 * ncomps; /* 2 DC scans; 4 AC scans per component */
}
/* Allocate space for script. */
/* We use permanent pool just in case application re-uses script. */
scanptr = (jpeg_scan_info *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
nscans * SIZEOF(jpeg_scan_info));
/* Allocate space for script.
* We need to put it in the permanent pool in case the application performs
* multiple compressions without changing the settings. To avoid a memory
* leak if jpeg_simple_progression is called repeatedly for the same JPEG
* object, we try to re-use previously allocated space, and we allocate
* enough space to handle YCbCr even if initially asked for grayscale.
*/
if (cinfo->script_space == NULL || cinfo->script_space_size < nscans) {
cinfo->script_space_size = MAX(nscans, 10);
cinfo->script_space = (jpeg_scan_info *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
cinfo->script_space_size * SIZEOF(jpeg_scan_info));
}
scanptr = cinfo->script_space;
cinfo->scan_info = scanptr;
cinfo->num_scans = nscans;

View File

@@ -1,7 +1,7 @@
/*
* jcphuff.c
*
* Copyright (C) 1995-1996, Thomas G. Lane.
* Copyright (C) 1995-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -147,22 +147,19 @@ start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics)
compptr = cinfo->cur_comp_info[ci];
/* Initialize DC predictions to 0 */
entropy->last_dc_val[ci] = 0;
/* Make sure requested tables are present */
/* (In gather mode, tables need not be allocated yet) */
/* Get table index */
if (is_DC_band) {
if (cinfo->Ah != 0) /* DC refinement needs no table */
continue;
tbl = compptr->dc_tbl_no;
if (tbl < 0 || tbl >= NUM_HUFF_TBLS ||
(cinfo->dc_huff_tbl_ptrs[tbl] == NULL && !gather_statistics))
ERREXIT1(cinfo,JERR_NO_HUFF_TABLE, tbl);
} else {
entropy->ac_tbl_no = tbl = compptr->ac_tbl_no;
if (tbl < 0 || tbl >= NUM_HUFF_TBLS ||
(cinfo->ac_huff_tbl_ptrs[tbl] == NULL && !gather_statistics))
ERREXIT1(cinfo,JERR_NO_HUFF_TABLE, tbl);
}
if (gather_statistics) {
/* Check for invalid table index */
/* (make_c_derived_tbl does this in the other path) */
if (tbl < 0 || tbl >= NUM_HUFF_TBLS)
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tbl);
/* Allocate and zero the statistics tables */
/* Note that jpeg_gen_optimal_table expects 257 entries in each table! */
if (entropy->count_ptrs[tbl] == NULL)
@@ -171,14 +168,10 @@ start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics)
257 * SIZEOF(long));
MEMZERO(entropy->count_ptrs[tbl], 257 * SIZEOF(long));
} else {
/* Compute derived values for Huffman tables */
/* Compute derived values for Huffman table */
/* We may do this more than once for a table, but it's not expensive */
if (is_DC_band)
jpeg_make_c_derived_tbl(cinfo, cinfo->dc_huff_tbl_ptrs[tbl],
& entropy->derived_tbls[tbl]);
else
jpeg_make_c_derived_tbl(cinfo, cinfo->ac_huff_tbl_ptrs[tbl],
& entropy->derived_tbls[tbl]);
jpeg_make_c_derived_tbl(cinfo, is_DC_band, tbl,
& entropy->derived_tbls[tbl]);
}
}
@@ -230,7 +223,6 @@ dump_buffer (phuff_entropy_ptr entropy)
* between calls, so 24 bits are sufficient.
*/
INLINE
LOCAL(void)
emit_bits (phuff_entropy_ptr entropy, unsigned int code, int size)
/* Emit some bits, unless we are in gather mode */
@@ -283,7 +275,6 @@ flush_bits (phuff_entropy_ptr entropy)
* Emit (or just count) a Huffman symbol.
*/
INLINE
LOCAL(void)
emit_symbol (phuff_entropy_ptr entropy, int tbl_no, int symbol)
{
@@ -329,6 +320,9 @@ emit_eobrun (phuff_entropy_ptr entropy)
nbits = 0;
while ((temp >>= 1))
nbits++;
/* safety check: shouldn't happen given limited correction-bit buffer */
if (nbits > 14)
ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE);
emit_symbol(entropy, entropy->ac_tbl_no, nbits << 4);
if (nbits)
@@ -427,6 +421,11 @@ encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
nbits++;
temp >>= 1;
}
/* Check for out-of-range coefficient values.
* Since we're encoding a difference, the range limit is twice as much.
*/
if (nbits > MAX_COEF_BITS+1)
ERREXIT(cinfo, JERR_BAD_DCT_COEF);
/* Count/emit the Huffman-coded symbol for the number of bits */
emit_symbol(entropy, compptr->dc_tbl_no, nbits);
@@ -523,6 +522,9 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
nbits = 1; /* there must be at least one 1 bit */
while ((temp >>= 1))
nbits++;
/* Check for out-of-range coefficient values */
if (nbits > MAX_COEF_BITS)
ERREXIT(cinfo, JERR_BAD_DCT_COEF);
/* Count/emit Huffman symbol for run length / number of bits */
emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + nbits);

View File

@@ -2,6 +2,7 @@
* jcsample.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -48,6 +49,7 @@
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jsimd.h"
/* Pointer to routine to downsample a single component */
@@ -494,7 +496,10 @@ jinit_downsampler (j_compress_ptr cinfo)
} else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
compptr->v_samp_factor == cinfo->max_v_samp_factor) {
smoothok = FALSE;
downsample->methods[ci] = h2v1_downsample;
if (jsimd_can_h2v1_downsample())
downsample->methods[ci] = jsimd_h2v1_downsample;
else
downsample->methods[ci] = h2v1_downsample;
} else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
compptr->v_samp_factor * 2 == cinfo->max_v_samp_factor) {
#ifdef INPUT_SMOOTHING_SUPPORTED
@@ -503,7 +508,10 @@ jinit_downsampler (j_compress_ptr cinfo)
downsample->pub.need_context_rows = TRUE;
} else
#endif
downsample->methods[ci] = h2v2_downsample;
if (jsimd_can_h2v2_downsample())
downsample->methods[ci] = jsimd_h2v2_downsample;
else
downsample->methods[ci] = h2v2_downsample;
} else if ((cinfo->max_h_samp_factor % compptr->h_samp_factor) == 0 &&
(cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0) {
smoothok = FALSE;

View File

@@ -1,7 +1,8 @@
/*
* jctrans.c
*
* Copyright (C) 1995-1996, Thomas G. Lane.
* Copyright (C) 1995-1998, Thomas G. Lane.
* Modified 2000-2009 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -76,6 +77,12 @@ jpeg_copy_critical_parameters (j_decompress_ptr srcinfo,
dstinfo->image_height = srcinfo->image_height;
dstinfo->input_components = srcinfo->num_components;
dstinfo->in_color_space = srcinfo->jpeg_color_space;
#if JPEG_LIB_VERSION >= 70
dstinfo->jpeg_width = srcinfo->output_width;
dstinfo->jpeg_height = srcinfo->output_height;
dstinfo->min_DCT_h_scaled_size = srcinfo->min_DCT_h_scaled_size;
dstinfo->min_DCT_v_scaled_size = srcinfo->min_DCT_v_scaled_size;
#endif
/* Initialize all parameters to default values */
jpeg_set_defaults(dstinfo);
/* jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB.
@@ -129,6 +136,23 @@ jpeg_copy_critical_parameters (j_decompress_ptr srcinfo,
* instead we rely on jpeg_set_colorspace to have made a suitable choice.
*/
}
/* Also copy JFIF version and resolution information, if available.
* Strictly speaking this isn't "critical" info, but it's nearly
* always appropriate to copy it if available. In particular,
* if the application chooses to copy JFIF 1.02 extension markers from
* the source file, we need to copy the version to make sure we don't
* emit a file that has 1.02 extensions but a claimed version of 1.01.
* We will *not*, however, copy version info from mislabeled "2.01" files.
*/
if (srcinfo->saw_JFIF_marker) {
if (srcinfo->JFIF_major_version == 1) {
dstinfo->JFIF_major_version = srcinfo->JFIF_major_version;
dstinfo->JFIF_minor_version = srcinfo->JFIF_minor_version;
}
dstinfo->density_unit = srcinfo->density_unit;
dstinfo->X_density = srcinfo->X_density;
dstinfo->Y_density = srcinfo->Y_density;
}
}
@@ -150,7 +174,11 @@ transencode_master_selection (j_compress_ptr cinfo,
/* Entropy encoding: either Huffman or arithmetic coding. */
if (cinfo->arith_code) {
#ifdef C_ARITH_CODING_SUPPORTED
jinit_arith_encoder(cinfo);
#else
ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
#endif
} else {
if (cinfo->progressive_mode) {
#ifdef C_PROGRESSIVE_SUPPORTED
@@ -170,7 +198,7 @@ transencode_master_selection (j_compress_ptr cinfo,
/* We can now tell the memory manager to allocate virtual arrays. */
(*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
/* Write the datastream header (SOI) immediately.
/* Write the datastream header (SOI, JFIF) immediately.
* Frame and scan headers are postponed till later.
* This lets application insert special markers after the SOI.
*/

View File

@@ -1,7 +1,7 @@
/*
* jdapimin.c
*
* Copyright (C) 1994-1996, Thomas G. Lane.
* Copyright (C) 1994-1998, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -39,13 +39,18 @@ jpeg_CreateDecompress (j_decompress_ptr cinfo, int version, size_t structsize)
ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE,
(int) SIZEOF(struct jpeg_decompress_struct), (int) structsize);
/* For debugging purposes, zero the whole master structure.
* But error manager pointer is already there, so save and restore it.
/* For debugging purposes, we zero the whole master structure.
* But the application has already set the err pointer, and may have set
* client_data, so we have to save and restore those fields.
* Note: if application hasn't set client_data, tools like Purify may
* complain here.
*/
{
struct jpeg_error_mgr * err = cinfo->err;
void * client_data = cinfo->client_data; /* ignore Purify complaint here */
MEMZERO(cinfo, SIZEOF(struct jpeg_decompress_struct));
cinfo->err = err;
cinfo->client_data = client_data;
}
cinfo->is_decompressor = TRUE;
@@ -67,6 +72,7 @@ jpeg_CreateDecompress (j_decompress_ptr cinfo, int version, size_t structsize)
/* Initialize marker processor so application can override methods
* for COM, APPn markers before calling jpeg_read_header.
*/
cinfo->marker_list = NULL;
jinit_marker_reader(cinfo);
/* And initialize the overall input controller. */
@@ -100,23 +106,6 @@ jpeg_abort_decompress (j_decompress_ptr cinfo)
}
/*
* Install a special processing method for COM or APPn markers.
*/
GLOBAL(void)
jpeg_set_marker_processor (j_decompress_ptr cinfo, int marker_code,
jpeg_marker_parser_method routine)
{
if (marker_code == JPEG_COM)
cinfo->marker->process_COM = routine;
else if (marker_code >= JPEG_APP0 && marker_code <= JPEG_APP0+15)
cinfo->marker->process_APPn[marker_code-JPEG_APP0] = routine;
else
ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);
}
/*
* Set default decompression parameters.
*/

View File

@@ -2,6 +2,7 @@
* jdapistd.c
*
* Copyright (C) 1994-1996, Thomas G. Lane.
* Copyright (C) 2010, 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.
*
@@ -17,6 +18,7 @@
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jpegcomp.h"
/* Forward declarations */
@@ -202,7 +204,7 @@ jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data,
}
/* Verify that at least one iMCU row can be returned. */
lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size;
lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->_min_DCT_scaled_size;
if (max_lines < lines_per_iMCU_row)
ERREXIT(cinfo, JERR_BUFFER_SIZE);

761
jdarith.c Normal file
View File

@@ -0,0 +1,761 @@
/*
* jdarith.c
*
* Developed 1997-2009 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains portable arithmetic entropy decoding routines for JPEG
* (implementing the ISO/IEC IS 10918-1 and CCITT Recommendation ITU-T T.81).
*
* Both sequential and progressive modes are supported in this single module.
*
* Suspension is not currently supported in this module.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
/* Expanded entropy decoder object for arithmetic decoding. */
typedef struct {
struct jpeg_entropy_decoder pub; /* public fields */
INT32 c; /* C register, base of coding interval + input bit buffer */
INT32 a; /* A register, normalized size of coding interval */
int ct; /* bit shift counter, # of bits left in bit buffer part of C */
/* init: ct = -16 */
/* run: ct = 0..7 */
/* error: ct = -1 */
int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
int dc_context[MAX_COMPS_IN_SCAN]; /* context index for DC conditioning */
unsigned int restarts_to_go; /* MCUs left in this restart interval */
/* Pointers to statistics areas (these workspaces have image lifespan) */
unsigned char * dc_stats[NUM_ARITH_TBLS];
unsigned char * ac_stats[NUM_ARITH_TBLS];
/* Statistics bin for coding with fixed probability 0.5 */
unsigned char fixed_bin[4];
} arith_entropy_decoder;
typedef arith_entropy_decoder * arith_entropy_ptr;
/* The following two definitions specify the allocation chunk size
* for the statistics area.
* According to sections F.1.4.4.1.3 and F.1.4.4.2, we need at least
* 49 statistics bins for DC, and 245 statistics bins for AC coding.
*
* We use a compact representation with 1 byte per statistics bin,
* thus the numbers directly represent byte sizes.
* This 1 byte per statistics bin contains the meaning of the MPS
* (more probable symbol) in the highest bit (mask 0x80), and the
* index into the probability estimation state machine table
* in the lower bits (mask 0x7F).
*/
#define DC_STAT_BINS 64
#define AC_STAT_BINS 256
LOCAL(int)
get_byte (j_decompress_ptr cinfo)
/* Read next input byte; we do not support suspension in this module. */
{
struct jpeg_source_mgr * src = cinfo->src;
if (src->bytes_in_buffer == 0)
if (! (*src->fill_input_buffer) (cinfo))
ERREXIT(cinfo, JERR_CANT_SUSPEND);
src->bytes_in_buffer--;
return GETJOCTET(*src->next_input_byte++);
}
/*
* The core arithmetic decoding routine (common in JPEG and JBIG).
* This needs to go as fast as possible.
* Machine-dependent optimization facilities
* are not utilized in this portable implementation.
* However, this code should be fairly efficient and
* may be a good base for further optimizations anyway.
*
* Return value is 0 or 1 (binary decision).
*
* Note: I've changed the handling of the code base & bit
* buffer register C compared to other implementations
* based on the standards layout & procedures.
* While it also contains both the actual base of the
* coding interval (16 bits) and the next-bits buffer,
* the cut-point between these two parts is floating
* (instead of fixed) with the bit shift counter CT.
* Thus, we also need only one (variable instead of
* fixed size) shift for the LPS/MPS decision, and
* we can get away with any renormalization update
* of C (except for new data insertion, of course).
*
* I've also introduced a new scheme for accessing
* the probability estimation state machine table,
* derived from Markus Kuhn's JBIG implementation.
*/
LOCAL(int)
arith_decode (j_decompress_ptr cinfo, unsigned char *st)
{
register arith_entropy_ptr e = (arith_entropy_ptr) cinfo->entropy;
register unsigned char nl, nm;
register INT32 qe, temp;
register int sv, data;
/* Renormalization & data input per section D.2.6 */
while (e->a < 0x8000L) {
if (--e->ct < 0) {
/* Need to fetch next data byte */
if (cinfo->unread_marker)
data = 0; /* stuff zero data */
else {
data = get_byte(cinfo); /* read next input byte */
if (data == 0xFF) { /* zero stuff or marker code */
do data = get_byte(cinfo);
while (data == 0xFF); /* swallow extra 0xFF bytes */
if (data == 0)
data = 0xFF; /* discard stuffed zero byte */
else {
/* Note: Different from the Huffman decoder, hitting
* a marker while processing the compressed data
* segment is legal in arithmetic coding.
* The convention is to supply zero data
* then until decoding is complete.
*/
cinfo->unread_marker = data;
data = 0;
}
}
}
e->c = (e->c << 8) | data; /* insert data into C register */
if ((e->ct += 8) < 0) /* update bit shift counter */
/* Need more initial bytes */
if (++e->ct == 0)
/* Got 2 initial bytes -> re-init A and exit loop */
e->a = 0x8000L; /* => e->a = 0x10000L after loop exit */
}
e->a <<= 1;
}
/* Fetch values from our compact representation of Table D.2:
* Qe values and probability estimation state machine
*/
sv = *st;
qe = jpeg_aritab[sv & 0x7F]; /* => Qe_Value */
nl = qe & 0xFF; qe >>= 8; /* Next_Index_LPS + Switch_MPS */
nm = qe & 0xFF; qe >>= 8; /* Next_Index_MPS */
/* Decode & estimation procedures per sections D.2.4 & D.2.5 */
temp = e->a - qe;
e->a = temp;
temp <<= e->ct;
if (e->c >= temp) {
e->c -= temp;
/* Conditional LPS (less probable symbol) exchange */
if (e->a < qe) {
e->a = qe;
*st = (sv & 0x80) ^ nm; /* Estimate_after_MPS */
} else {
e->a = qe;
*st = (sv & 0x80) ^ nl; /* Estimate_after_LPS */
sv ^= 0x80; /* Exchange LPS/MPS */
}
} else if (e->a < 0x8000L) {
/* Conditional MPS (more probable symbol) exchange */
if (e->a < qe) {
*st = (sv & 0x80) ^ nl; /* Estimate_after_LPS */
sv ^= 0x80; /* Exchange LPS/MPS */
} else {
*st = (sv & 0x80) ^ nm; /* Estimate_after_MPS */
}
}
return sv >> 7;
}
/*
* Check for a restart marker & resynchronize decoder.
*/
LOCAL(void)
process_restart (j_decompress_ptr cinfo)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
int ci;
jpeg_component_info * compptr;
/* Advance past the RSTn marker */
if (! (*cinfo->marker->read_restart_marker) (cinfo))
ERREXIT(cinfo, JERR_CANT_SUSPEND);
/* Re-initialize statistics areas */
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
if (! cinfo->progressive_mode || (cinfo->Ss == 0 && cinfo->Ah == 0)) {
MEMZERO(entropy->dc_stats[compptr->dc_tbl_no], DC_STAT_BINS);
/* Reset DC predictions to 0 */
entropy->last_dc_val[ci] = 0;
entropy->dc_context[ci] = 0;
}
if (! cinfo->progressive_mode || cinfo->Ss) {
MEMZERO(entropy->ac_stats[compptr->ac_tbl_no], AC_STAT_BINS);
}
}
/* Reset arithmetic decoding variables */
entropy->c = 0;
entropy->a = 0;
entropy->ct = -16; /* force reading 2 initial bytes to fill C */
/* Reset restart counter */
entropy->restarts_to_go = cinfo->restart_interval;
}
/*
* Arithmetic MCU decoding.
* Each of these routines decodes and returns one MCU's worth of
* arithmetic-compressed coefficients.
* The coefficients are reordered from zigzag order into natural array order,
* but are not dequantized.
*
* The i'th block of the MCU is stored into the block pointed to by
* MCU_data[i]. WE ASSUME THIS AREA IS INITIALLY ZEROED BY THE CALLER.
*/
/*
* MCU decoding for DC initial scan (either spectral selection,
* or first pass of successive approximation).
*/
METHODDEF(boolean)
decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
JBLOCKROW block;
unsigned char *st;
int blkn, ci, tbl, sign;
int v, m;
/* Process restart marker if needed */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0)
process_restart(cinfo);
entropy->restarts_to_go--;
}
if (entropy->ct == -1) return TRUE; /* if error do nothing */
/* Outer loop handles each block in the MCU */
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
block = MCU_data[blkn];
ci = cinfo->MCU_membership[blkn];
tbl = cinfo->cur_comp_info[ci]->dc_tbl_no;
/* Sections F.2.4.1 & F.1.4.4.1: Decoding of DC coefficients */
/* Table F.4: Point to statistics bin S0 for DC coefficient coding */
st = entropy->dc_stats[tbl] + entropy->dc_context[ci];
/* Figure F.19: Decode_DC_DIFF */
if (arith_decode(cinfo, st) == 0)
entropy->dc_context[ci] = 0;
else {
/* Figure F.21: Decoding nonzero value v */
/* Figure F.22: Decoding the sign of v */
sign = arith_decode(cinfo, st + 1);
st += 2; st += sign;
/* Figure F.23: Decoding the magnitude category of v */
if ((m = arith_decode(cinfo, st)) != 0) {
st = entropy->dc_stats[tbl] + 20; /* Table F.4: X1 = 20 */
while (arith_decode(cinfo, st)) {
if ((m <<= 1) == 0x8000) {
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
entropy->ct = -1; /* magnitude overflow */
return TRUE;
}
st += 1;
}
}
/* Section F.1.4.4.1.2: Establish dc_context conditioning category */
if (m < (int) ((1L << cinfo->arith_dc_L[tbl]) >> 1))
entropy->dc_context[ci] = 0; /* zero diff category */
else if (m > (int) ((1L << cinfo->arith_dc_U[tbl]) >> 1))
entropy->dc_context[ci] = 12 + (sign * 4); /* large diff category */
else
entropy->dc_context[ci] = 4 + (sign * 4); /* small diff category */
v = m;
/* Figure F.24: Decoding the magnitude bit pattern of v */
st += 14;
while (m >>= 1)
if (arith_decode(cinfo, st)) v |= m;
v += 1; if (sign) v = -v;
entropy->last_dc_val[ci] += v;
}
/* Scale and output the DC coefficient (assumes jpeg_natural_order[0]=0) */
(*block)[0] = (JCOEF) (entropy->last_dc_val[ci] << cinfo->Al);
}
return TRUE;
}
/*
* MCU decoding for AC initial scan (either spectral selection,
* or first pass of successive approximation).
*/
METHODDEF(boolean)
decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
JBLOCKROW block;
unsigned char *st;
int tbl, sign, k;
int v, m;
/* Process restart marker if needed */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0)
process_restart(cinfo);
entropy->restarts_to_go--;
}
if (entropy->ct == -1) return TRUE; /* if error do nothing */
/* There is always only one block per MCU */
block = MCU_data[0];
tbl = cinfo->cur_comp_info[0]->ac_tbl_no;
/* Sections F.2.4.2 & F.1.4.4.2: Decoding of AC coefficients */
/* Figure F.20: Decode_AC_coefficients */
for (k = cinfo->Ss; k <= cinfo->Se; k++) {
st = entropy->ac_stats[tbl] + 3 * (k - 1);
if (arith_decode(cinfo, st)) break; /* EOB flag */
while (arith_decode(cinfo, st + 1) == 0) {
st += 3; k++;
if (k > cinfo->Se) {
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
entropy->ct = -1; /* spectral overflow */
return TRUE;
}
}
/* Figure F.21: Decoding nonzero value v */
/* Figure F.22: Decoding the sign of v */
sign = arith_decode(cinfo, entropy->fixed_bin);
st += 2;
/* Figure F.23: Decoding the magnitude category of v */
if ((m = arith_decode(cinfo, st)) != 0) {
if (arith_decode(cinfo, st)) {
m <<= 1;
st = entropy->ac_stats[tbl] +
(k <= cinfo->arith_ac_K[tbl] ? 189 : 217);
while (arith_decode(cinfo, st)) {
if ((m <<= 1) == 0x8000) {
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
entropy->ct = -1; /* magnitude overflow */
return TRUE;
}
st += 1;
}
}
}
v = m;
/* Figure F.24: Decoding the magnitude bit pattern of v */
st += 14;
while (m >>= 1)
if (arith_decode(cinfo, st)) v |= m;
v += 1; if (sign) v = -v;
/* Scale and output coefficient in natural (dezigzagged) order */
(*block)[jpeg_natural_order[k]] = (JCOEF) (v << cinfo->Al);
}
return TRUE;
}
/*
* MCU decoding for DC successive approximation refinement scan.
*/
METHODDEF(boolean)
decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
unsigned char *st;
int p1, blkn;
/* Process restart marker if needed */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0)
process_restart(cinfo);
entropy->restarts_to_go--;
}
st = entropy->fixed_bin; /* use fixed probability estimation */
p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */
/* Outer loop handles each block in the MCU */
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
/* Encoded data is simply the next bit of the two's-complement DC value */
if (arith_decode(cinfo, st))
MCU_data[blkn][0][0] |= p1;
}
return TRUE;
}
/*
* MCU decoding for AC successive approximation refinement scan.
*/
METHODDEF(boolean)
decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
JBLOCKROW block;
JCOEFPTR thiscoef;
unsigned char *st;
int tbl, k, kex;
int p1, m1;
/* Process restart marker if needed */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0)
process_restart(cinfo);
entropy->restarts_to_go--;
}
if (entropy->ct == -1) return TRUE; /* if error do nothing */
/* There is always only one block per MCU */
block = MCU_data[0];
tbl = cinfo->cur_comp_info[0]->ac_tbl_no;
p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */
m1 = (-1) << cinfo->Al; /* -1 in the bit position being coded */
/* Establish EOBx (previous stage end-of-block) index */
for (kex = cinfo->Se; kex > 0; kex--)
if ((*block)[jpeg_natural_order[kex]]) break;
for (k = cinfo->Ss; k <= cinfo->Se; k++) {
st = entropy->ac_stats[tbl] + 3 * (k - 1);
if (k > kex)
if (arith_decode(cinfo, st)) break; /* EOB flag */
for (;;) {
thiscoef = *block + jpeg_natural_order[k];
if (*thiscoef) { /* previously nonzero coef */
if (arith_decode(cinfo, st + 2)) {
if (*thiscoef < 0)
*thiscoef += m1;
else
*thiscoef += p1;
}
break;
}
if (arith_decode(cinfo, st + 1)) { /* newly nonzero coef */
if (arith_decode(cinfo, entropy->fixed_bin))
*thiscoef = m1;
else
*thiscoef = p1;
break;
}
st += 3; k++;
if (k > cinfo->Se) {
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
entropy->ct = -1; /* spectral overflow */
return TRUE;
}
}
}
return TRUE;
}
/*
* Decode one MCU's worth of arithmetic-compressed coefficients.
*/
METHODDEF(boolean)
decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
jpeg_component_info * compptr;
JBLOCKROW block;
unsigned char *st;
int blkn, ci, tbl, sign, k;
int v, m;
/* Process restart marker if needed */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0)
process_restart(cinfo);
entropy->restarts_to_go--;
}
if (entropy->ct == -1) return TRUE; /* if error do nothing */
/* Outer loop handles each block in the MCU */
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
block = MCU_data[blkn];
ci = cinfo->MCU_membership[blkn];
compptr = cinfo->cur_comp_info[ci];
/* Sections F.2.4.1 & F.1.4.4.1: Decoding of DC coefficients */
tbl = compptr->dc_tbl_no;
/* Table F.4: Point to statistics bin S0 for DC coefficient coding */
st = entropy->dc_stats[tbl] + entropy->dc_context[ci];
/* Figure F.19: Decode_DC_DIFF */
if (arith_decode(cinfo, st) == 0)
entropy->dc_context[ci] = 0;
else {
/* Figure F.21: Decoding nonzero value v */
/* Figure F.22: Decoding the sign of v */
sign = arith_decode(cinfo, st + 1);
st += 2; st += sign;
/* Figure F.23: Decoding the magnitude category of v */
if ((m = arith_decode(cinfo, st)) != 0) {
st = entropy->dc_stats[tbl] + 20; /* Table F.4: X1 = 20 */
while (arith_decode(cinfo, st)) {
if ((m <<= 1) == 0x8000) {
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
entropy->ct = -1; /* magnitude overflow */
return TRUE;
}
st += 1;
}
}
/* Section F.1.4.4.1.2: Establish dc_context conditioning category */
if (m < (int) ((1L << cinfo->arith_dc_L[tbl]) >> 1))
entropy->dc_context[ci] = 0; /* zero diff category */
else if (m > (int) ((1L << cinfo->arith_dc_U[tbl]) >> 1))
entropy->dc_context[ci] = 12 + (sign * 4); /* large diff category */
else
entropy->dc_context[ci] = 4 + (sign * 4); /* small diff category */
v = m;
/* Figure F.24: Decoding the magnitude bit pattern of v */
st += 14;
while (m >>= 1)
if (arith_decode(cinfo, st)) v |= m;
v += 1; if (sign) v = -v;
entropy->last_dc_val[ci] += v;
}
(*block)[0] = (JCOEF) entropy->last_dc_val[ci];
/* Sections F.2.4.2 & F.1.4.4.2: Decoding of AC coefficients */
tbl = compptr->ac_tbl_no;
/* Figure F.20: Decode_AC_coefficients */
for (k = 1; k <= DCTSIZE2 - 1; k++) {
st = entropy->ac_stats[tbl] + 3 * (k - 1);
if (arith_decode(cinfo, st)) break; /* EOB flag */
while (arith_decode(cinfo, st + 1) == 0) {
st += 3; k++;
if (k > DCTSIZE2 - 1) {
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
entropy->ct = -1; /* spectral overflow */
return TRUE;
}
}
/* Figure F.21: Decoding nonzero value v */
/* Figure F.22: Decoding the sign of v */
sign = arith_decode(cinfo, entropy->fixed_bin);
st += 2;
/* Figure F.23: Decoding the magnitude category of v */
if ((m = arith_decode(cinfo, st)) != 0) {
if (arith_decode(cinfo, st)) {
m <<= 1;
st = entropy->ac_stats[tbl] +
(k <= cinfo->arith_ac_K[tbl] ? 189 : 217);
while (arith_decode(cinfo, st)) {
if ((m <<= 1) == 0x8000) {
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
entropy->ct = -1; /* magnitude overflow */
return TRUE;
}
st += 1;
}
}
}
v = m;
/* Figure F.24: Decoding the magnitude bit pattern of v */
st += 14;
while (m >>= 1)
if (arith_decode(cinfo, st)) v |= m;
v += 1; if (sign) v = -v;
(*block)[jpeg_natural_order[k]] = (JCOEF) v;
}
}
return TRUE;
}
/*
* Initialize for an arithmetic-compressed scan.
*/
METHODDEF(void)
start_pass (j_decompress_ptr cinfo)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
int ci, tbl;
jpeg_component_info * compptr;
if (cinfo->progressive_mode) {
/* Validate progressive scan parameters */
if (cinfo->Ss == 0) {
if (cinfo->Se != 0)
goto bad;
} else {
/* need not check Ss/Se < 0 since they came from unsigned bytes */
if (cinfo->Se < cinfo->Ss || cinfo->Se > DCTSIZE2 - 1)
goto bad;
/* AC scans may have only one component */
if (cinfo->comps_in_scan != 1)
goto bad;
}
if (cinfo->Ah != 0) {
/* Successive approximation refinement scan: must have Al = Ah-1. */
if (cinfo->Ah-1 != cinfo->Al)
goto bad;
}
if (cinfo->Al > 13) { /* need not check for < 0 */
bad:
ERREXIT4(cinfo, JERR_BAD_PROGRESSION,
cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al);
}
/* Update progression status, and verify that scan order is legal.
* Note that inter-scan inconsistencies are treated as warnings
* not fatal errors ... not clear if this is right way to behave.
*/
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
int coefi, cindex = cinfo->cur_comp_info[ci]->component_index;
int *coef_bit_ptr = & cinfo->coef_bits[cindex][0];
if (cinfo->Ss && coef_bit_ptr[0] < 0) /* AC without prior DC scan */
WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, 0);
for (coefi = cinfo->Ss; coefi <= cinfo->Se; coefi++) {
int expected = (coef_bit_ptr[coefi] < 0) ? 0 : coef_bit_ptr[coefi];
if (cinfo->Ah != expected)
WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, coefi);
coef_bit_ptr[coefi] = cinfo->Al;
}
}
/* Select MCU decoding routine */
if (cinfo->Ah == 0) {
if (cinfo->Ss == 0)
entropy->pub.decode_mcu = decode_mcu_DC_first;
else
entropy->pub.decode_mcu = decode_mcu_AC_first;
} else {
if (cinfo->Ss == 0)
entropy->pub.decode_mcu = decode_mcu_DC_refine;
else
entropy->pub.decode_mcu = decode_mcu_AC_refine;
}
} else {
/* Check that the scan parameters Ss, Se, Ah/Al are OK for sequential JPEG.
* This ought to be an error condition, but we make it a warning.
*/
if (cinfo->Ss != 0 || cinfo->Ah != 0 || cinfo->Al != 0 ||
(cinfo->Se < DCTSIZE2 && cinfo->Se != DCTSIZE2 - 1))
WARNMS(cinfo, JWRN_NOT_SEQUENTIAL);
/* Select MCU decoding routine */
entropy->pub.decode_mcu = decode_mcu;
}
/* Allocate & initialize requested statistics areas */
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
if (! cinfo->progressive_mode || (cinfo->Ss == 0 && cinfo->Ah == 0)) {
tbl = compptr->dc_tbl_no;
if (tbl < 0 || tbl >= NUM_ARITH_TBLS)
ERREXIT1(cinfo, JERR_NO_ARITH_TABLE, tbl);
if (entropy->dc_stats[tbl] == NULL)
entropy->dc_stats[tbl] = (unsigned char *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, DC_STAT_BINS);
MEMZERO(entropy->dc_stats[tbl], DC_STAT_BINS);
/* Initialize DC predictions to 0 */
entropy->last_dc_val[ci] = 0;
entropy->dc_context[ci] = 0;
}
if (! cinfo->progressive_mode || cinfo->Ss) {
tbl = compptr->ac_tbl_no;
if (tbl < 0 || tbl >= NUM_ARITH_TBLS)
ERREXIT1(cinfo, JERR_NO_ARITH_TABLE, tbl);
if (entropy->ac_stats[tbl] == NULL)
entropy->ac_stats[tbl] = (unsigned char *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, AC_STAT_BINS);
MEMZERO(entropy->ac_stats[tbl], AC_STAT_BINS);
}
}
/* Initialize arithmetic decoding variables */
entropy->c = 0;
entropy->a = 0;
entropy->ct = -16; /* force reading 2 initial bytes to fill C */
/* Initialize restart counter */
entropy->restarts_to_go = cinfo->restart_interval;
}
/*
* Module initialization routine for arithmetic entropy decoding.
*/
GLOBAL(void)
jinit_arith_decoder (j_decompress_ptr cinfo)
{
arith_entropy_ptr entropy;
int i;
entropy = (arith_entropy_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(arith_entropy_decoder));
cinfo->entropy = (struct jpeg_entropy_decoder *) entropy;
entropy->pub.start_pass = start_pass;
/* Mark tables unallocated */
for (i = 0; i < NUM_ARITH_TBLS; i++) {
entropy->dc_stats[i] = NULL;
entropy->ac_stats[i] = NULL;
}
/* Initialize index for fixed probability estimation */
entropy->fixed_bin[0] = 113;
if (cinfo->progressive_mode) {
/* Create progression status table */
int *coef_bit_ptr, ci;
cinfo->coef_bits = (int (*)[DCTSIZE2])
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
cinfo->num_components*DCTSIZE2*SIZEOF(int));
coef_bit_ptr = & cinfo->coef_bits[0][0];
for (ci = 0; ci < cinfo->num_components; ci++)
for (i = 0; i < DCTSIZE2; i++)
*coef_bit_ptr++ = -1;
}
}

View File

@@ -2,13 +2,14 @@
* jdatadst.c
*
* Copyright (C) 1994-1996, Thomas G. Lane.
* Modified 2009 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains compression data destination routines for the case of
* emitting JPEG data to a file (or any stdio stream). While these routines
* are sufficient for most applications, some will want to use a different
* destination manager.
* emitting JPEG data to memory or to a file (or any stdio stream).
* While these routines are sufficient for most applications,
* some will want to use a different destination manager.
* IMPORTANT: we assume that fwrite() will correctly transcribe an array of
* JOCTETs into 8-bit-wide elements on external storage. If char is wider
* than 8 bits on your machine, you may need to do some tweaking.
@@ -19,6 +20,11 @@
#include "jpeglib.h"
#include "jerror.h"
#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare malloc(),free() */
extern void * malloc JPP((size_t size));
extern void free JPP((void *ptr));
#endif
/* Expanded data destination object for stdio output */
@@ -34,6 +40,23 @@ typedef my_destination_mgr * my_dest_ptr;
#define OUTPUT_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */
#if JPEG_LIB_VERSION >= 80
/* Expanded data destination object for memory output */
typedef struct {
struct jpeg_destination_mgr pub; /* public fields */
unsigned char ** outbuffer; /* target buffer */
unsigned long * outsize;
unsigned char * newbuffer; /* newly allocated buffer */
JOCTET * buffer; /* start of buffer */
size_t bufsize;
} my_mem_destination_mgr;
typedef my_mem_destination_mgr * my_mem_dest_ptr;
#endif
/*
* Initialize destination --- called by jpeg_start_compress
* before any data is actually written.
@@ -53,6 +76,14 @@ init_destination (j_compress_ptr cinfo)
dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
}
#if JPEG_LIB_VERSION >= 80
METHODDEF(void)
init_mem_destination (j_compress_ptr cinfo)
{
/* no work necessary here */
}
#endif
/*
* Empty the output buffer --- called whenever buffer fills up.
@@ -92,6 +123,38 @@ empty_output_buffer (j_compress_ptr cinfo)
return TRUE;
}
#if JPEG_LIB_VERSION >= 80
METHODDEF(boolean)
empty_mem_output_buffer (j_compress_ptr cinfo)
{
size_t nextsize;
JOCTET * nextbuffer;
my_mem_dest_ptr dest = (my_mem_dest_ptr) cinfo->dest;
/* Try to allocate new buffer with double size */
nextsize = dest->bufsize * 2;
nextbuffer = malloc(nextsize);
if (nextbuffer == NULL)
ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10);
MEMCOPY(nextbuffer, dest->buffer, dest->bufsize);
if (dest->newbuffer != NULL)
free(dest->newbuffer);
dest->newbuffer = nextbuffer;
dest->pub.next_output_byte = nextbuffer + dest->bufsize;
dest->pub.free_in_buffer = dest->bufsize;
dest->buffer = nextbuffer;
dest->bufsize = nextsize;
return TRUE;
}
#endif
/*
* Terminate destination --- called by jpeg_finish_compress
@@ -119,6 +182,17 @@ term_destination (j_compress_ptr cinfo)
ERREXIT(cinfo, JERR_FILE_WRITE);
}
#if JPEG_LIB_VERSION >= 80
METHODDEF(void)
term_mem_destination (j_compress_ptr cinfo)
{
my_mem_dest_ptr dest = (my_mem_dest_ptr) cinfo->dest;
*dest->outbuffer = dest->buffer;
*dest->outsize = dest->bufsize - dest->pub.free_in_buffer;
}
#endif
/*
* Prepare for output to a stdio stream.
@@ -149,3 +223,55 @@ jpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile)
dest->pub.term_destination = term_destination;
dest->outfile = outfile;
}
#if JPEG_LIB_VERSION >= 80
/*
* Prepare for output to a memory buffer.
* The caller may supply an own initial buffer with appropriate size.
* Otherwise, or when the actual data output exceeds the given size,
* the library adapts the buffer size as necessary.
* The standard library functions malloc/free are used for allocating
* larger memory, so the buffer is available to the application after
* finishing compression, and then the application is responsible for
* freeing the requested memory.
*/
GLOBAL(void)
jpeg_mem_dest (j_compress_ptr cinfo,
unsigned char ** outbuffer, unsigned long * outsize)
{
my_mem_dest_ptr dest;
if (outbuffer == NULL || outsize == NULL) /* sanity check */
ERREXIT(cinfo, JERR_BUFFER_SIZE);
/* The destination object is made permanent so that multiple JPEG images
* can be written to the same buffer without re-executing jpeg_mem_dest.
*/
if (cinfo->dest == NULL) { /* first time for this JPEG object? */
cinfo->dest = (struct jpeg_destination_mgr *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
SIZEOF(my_mem_destination_mgr));
}
dest = (my_mem_dest_ptr) cinfo->dest;
dest->pub.init_destination = init_mem_destination;
dest->pub.empty_output_buffer = empty_mem_output_buffer;
dest->pub.term_destination = term_mem_destination;
dest->outbuffer = outbuffer;
dest->outsize = outsize;
dest->newbuffer = NULL;
if (*outbuffer == NULL || *outsize == 0) {
/* Allocate initial buffer */
dest->newbuffer = *outbuffer = malloc(OUTPUT_BUF_SIZE);
if (dest->newbuffer == NULL)
ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10);
*outsize = OUTPUT_BUF_SIZE;
}
dest->pub.next_output_byte = dest->buffer = *outbuffer;
dest->pub.free_in_buffer = dest->bufsize = *outsize;
}
#endif

View File

@@ -2,13 +2,14 @@
* jdatasrc.c
*
* Copyright (C) 1994-1996, Thomas G. Lane.
* Modified 2009-2010 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains decompression data source routines for the case of
* reading JPEG data from a file (or any stdio stream). While these routines
* are sufficient for most applications, some will want to use a different
* source manager.
* reading JPEG data from memory or from a file (or any stdio stream).
* While these routines are sufficient for most applications,
* some will want to use a different source manager.
* IMPORTANT: we assume that fread() will correctly transcribe an array of
* JOCTETs from 8-bit-wide elements on external storage. If char is wider
* than 8 bits on your machine, you may need to do some tweaking.
@@ -52,6 +53,14 @@ init_source (j_decompress_ptr cinfo)
src->start_of_file = TRUE;
}
#if JPEG_LIB_VERSION >= 80
METHODDEF(void)
init_mem_source (j_decompress_ptr cinfo)
{
/* no work necessary here */
}
#endif
/*
* Fill the input buffer --- called whenever buffer is emptied.
@@ -111,6 +120,28 @@ fill_input_buffer (j_decompress_ptr cinfo)
return TRUE;
}
#if JPEG_LIB_VERSION >= 80
METHODDEF(boolean)
fill_mem_input_buffer (j_decompress_ptr cinfo)
{
static JOCTET mybuffer[4];
/* The whole JPEG data is expected to reside in the supplied memory
* buffer, so any request for more data beyond the given buffer size
* is treated as an error.
*/
WARNMS(cinfo, JWRN_JPEG_EOF);
/* Insert a fake EOI marker */
mybuffer[0] = (JOCTET) 0xFF;
mybuffer[1] = (JOCTET) JPEG_EOI;
cinfo->src->next_input_byte = mybuffer;
cinfo->src->bytes_in_buffer = 2;
return TRUE;
}
#endif
/*
* Skip data --- used to skip over a potentially large amount of
@@ -127,22 +158,22 @@ fill_input_buffer (j_decompress_ptr cinfo)
METHODDEF(void)
skip_input_data (j_decompress_ptr cinfo, long num_bytes)
{
my_src_ptr src = (my_src_ptr) cinfo->src;
struct jpeg_source_mgr * src = cinfo->src;
/* Just a dumb implementation for now. Could use fseek() except
* it doesn't work on pipes. Not clear that being smart is worth
* any trouble anyway --- large skips are infrequent.
*/
if (num_bytes > 0) {
while (num_bytes > (long) src->pub.bytes_in_buffer) {
num_bytes -= (long) src->pub.bytes_in_buffer;
(void) fill_input_buffer(cinfo);
while (num_bytes > (long) src->bytes_in_buffer) {
num_bytes -= (long) src->bytes_in_buffer;
(void) (*src->fill_input_buffer) (cinfo);
/* note we assume that fill_input_buffer will never return FALSE,
* so suspension need not be handled.
*/
}
src->pub.next_input_byte += (size_t) num_bytes;
src->pub.bytes_in_buffer -= (size_t) num_bytes;
src->next_input_byte += (size_t) num_bytes;
src->bytes_in_buffer -= (size_t) num_bytes;
}
}
@@ -210,3 +241,40 @@ jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile)
src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
src->pub.next_input_byte = NULL; /* until buffer loaded */
}
#if JPEG_LIB_VERSION >= 80
/*
* Prepare for input from a supplied memory buffer.
* The buffer must contain the whole JPEG data.
*/
GLOBAL(void)
jpeg_mem_src (j_decompress_ptr cinfo,
unsigned char * inbuffer, unsigned long insize)
{
struct jpeg_source_mgr * src;
if (inbuffer == NULL || insize == 0) /* Treat empty input as fatal error */
ERREXIT(cinfo, JERR_INPUT_EMPTY);
/* The source object is made permanent so that a series of JPEG images
* can be read from the same buffer by calling jpeg_mem_src only before
* the first one.
*/
if (cinfo->src == NULL) { /* first time for this JPEG object? */
cinfo->src = (struct jpeg_source_mgr *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
SIZEOF(struct jpeg_source_mgr));
}
src = cinfo->src;
src->init_source = init_mem_source;
src->fill_input_buffer = fill_mem_input_buffer;
src->skip_input_data = skip_input_data;
src->resync_to_restart = jpeg_resync_to_restart; /* use default method */
src->term_source = term_source;
src->bytes_in_buffer = (size_t) insize;
src->next_input_byte = (JOCTET *) inbuffer;
}
#endif

View File

@@ -1,7 +1,8 @@
/*
* jdcoefct.c
*
* Copyright (C) 1994-1996, Thomas G. Lane.
* Copyright (C) 1994-1997, Thomas G. Lane.
* Copyright (C) 2010, 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.
*
@@ -17,6 +18,7 @@
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jpegcomp.h"
/* Block smoothing is only applicable for progressive JPEG, so: */
#ifndef D_PROGRESSIVE_SUPPORTED
@@ -47,6 +49,9 @@ typedef struct {
*/
JBLOCKROW MCU_buffer[D_MAX_BLOCKS_IN_MCU];
/* Temporary workspace for one MCU */
JCOEF * workspace;
#ifdef D_MULTISCAN_FILES_SUPPORTED
/* In multi-pass modes, we need a virtual block array for each component. */
jvirt_barray_ptr whole_image[MAX_COMPONENTS];
@@ -139,8 +144,8 @@ start_output_pass (j_decompress_ptr cinfo)
* Input and output must run in lockstep since we have only a one-MCU buffer.
* Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
*
* NB: output_buf contains a plane for each component in image.
* For single pass, this is the same as the components in the scan.
* NB: output_buf contains a plane for each component in image,
* which we index according to the component's SOF position.
*/
METHODDEF(int)
@@ -186,7 +191,8 @@ decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
inverse_DCT = cinfo->idct->inverse_DCT[compptr->component_index];
useful_width = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
: compptr->last_col_width;
output_ptr = output_buf[ci] + yoffset * compptr->DCT_scaled_size;
output_ptr = output_buf[compptr->component_index] +
yoffset * compptr->_DCT_scaled_size;
start_col = MCU_col_num * compptr->MCU_sample_width;
for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
if (cinfo->input_iMCU_row < last_iMCU_row ||
@@ -196,11 +202,11 @@ decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
(*inverse_DCT) (cinfo, compptr,
(JCOEFPTR) coef->MCU_buffer[blkn+xindex],
output_ptr, output_col);
output_col += compptr->DCT_scaled_size;
output_col += compptr->_DCT_scaled_size;
}
}
blkn += compptr->MCU_width;
output_ptr += compptr->DCT_scaled_size;
output_ptr += compptr->_DCT_scaled_size;
}
}
}
@@ -361,9 +367,9 @@ decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
(*inverse_DCT) (cinfo, compptr, (JCOEFPTR) buffer_ptr,
output_ptr, output_col);
buffer_ptr++;
output_col += compptr->DCT_scaled_size;
output_col += compptr->_DCT_scaled_size;
}
output_ptr += compptr->DCT_scaled_size;
output_ptr += compptr->_DCT_scaled_size;
}
}
@@ -470,13 +476,16 @@ decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
jpeg_component_info *compptr;
inverse_DCT_method_ptr inverse_DCT;
boolean first_row, last_row;
JBLOCK workspace;
JCOEF * workspace;
int *coef_bits;
JQUANT_TBL *quanttbl;
INT32 Q00,Q01,Q02,Q10,Q11,Q20, num;
int DC1,DC2,DC3,DC4,DC5,DC6,DC7,DC8,DC9;
int Al, pred;
/* Keep a local variable to avoid looking it up more than once */
workspace = coef->workspace;
/* Force some input to be done if we are getting ahead of the input. */
while (cinfo->input_scan_number <= cinfo->output_scan_number &&
! cinfo->inputctl->eoi_reached) {
@@ -653,9 +662,9 @@ decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
DC4 = DC5; DC5 = DC6;
DC7 = DC8; DC8 = DC9;
buffer_ptr++, prev_block_row++, next_block_row++;
output_col += compptr->DCT_scaled_size;
output_col += compptr->_DCT_scaled_size;
}
output_ptr += compptr->DCT_scaled_size;
output_ptr += compptr->_DCT_scaled_size;
}
}
@@ -732,4 +741,9 @@ jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
coef->pub.decompress_data = decompress_onepass;
coef->pub.coef_arrays = NULL; /* flag for no virtual arrays */
}
/* Allocate the workspace buffer */
coef->workspace = (JCOEF *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(JCOEF) * DCTSIZE2);
}

View File

@@ -1,7 +1,9 @@
/*
* jdcolor.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Copyright (C) 1991-1997, Thomas G. Lane.
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
* Copyright (C) 2009, 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.
*
@@ -11,6 +13,7 @@
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jsimd.h"
/* Private subobject */
@@ -146,12 +149,12 @@ ycc_rgb_convert (j_decompress_ptr cinfo,
cb = GETJSAMPLE(inptr1[col]);
cr = GETJSAMPLE(inptr2[col]);
/* Range-limiting is essential due to noise introduced by DCT losses. */
outptr[RGB_RED] = range_limit[y + Crrtab[cr]];
outptr[RGB_GREEN] = range_limit[y +
outptr[rgb_red[cinfo->out_color_space]] = range_limit[y + Crrtab[cr]];
outptr[rgb_green[cinfo->out_color_space]] = range_limit[y +
((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
SCALEBITS))];
outptr[RGB_BLUE] = range_limit[y + Cbbtab[cb]];
outptr += RGB_PIXELSIZE;
outptr[rgb_blue[cinfo->out_color_space]] = range_limit[y + Cbbtab[cb]];
outptr += rgb_pixelsize[cinfo->out_color_space];
}
}
}
@@ -207,6 +210,38 @@ grayscale_convert (j_decompress_ptr cinfo,
}
/*
* Convert grayscale to RGB: just duplicate the graylevel three times.
* This is provided to support applications that don't want to cope
* with grayscale as a separate case.
*/
METHODDEF(void)
gray_rgb_convert (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION input_row,
JSAMPARRAY output_buf, int num_rows)
{
register JSAMPROW inptr, outptr;
JSAMPLE *maxinptr;
register JDIMENSION col;
JDIMENSION num_cols = cinfo->output_width;
int rindex = rgb_red[cinfo->out_color_space];
int gindex = rgb_green[cinfo->out_color_space];
int bindex = rgb_blue[cinfo->out_color_space];
int rgbstride = rgb_pixelsize[cinfo->out_color_space];
while (--num_rows >= 0) {
inptr = input_buf[0][input_row++];
maxinptr = &inptr[num_cols];
outptr = *output_buf++;
for (; inptr < maxinptr; inptr++, outptr += rgbstride) {
/* We can dispense with GETJSAMPLE() here */
outptr[rindex] = outptr[gindex] = outptr[bindex] = *inptr;
}
}
}
/*
* Adobe-style YCCK->CMYK conversion.
* We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
@@ -329,11 +364,24 @@ jinit_color_deconverter (j_decompress_ptr cinfo)
break;
case JCS_RGB:
cinfo->out_color_components = RGB_PIXELSIZE;
case JCS_EXT_RGB:
case JCS_EXT_RGBX:
case JCS_EXT_BGR:
case JCS_EXT_BGRX:
case JCS_EXT_XBGR:
case JCS_EXT_XRGB:
cinfo->out_color_components = rgb_pixelsize[cinfo->out_color_space];
if (cinfo->jpeg_color_space == JCS_YCbCr) {
cconvert->pub.color_convert = ycc_rgb_convert;
build_ycc_rgb_table(cinfo);
} else if (cinfo->jpeg_color_space == JCS_RGB && RGB_PIXELSIZE == 3) {
if (jsimd_can_ycc_rgb())
cconvert->pub.color_convert = jsimd_ycc_rgb_convert;
else {
cconvert->pub.color_convert = ycc_rgb_convert;
build_ycc_rgb_table(cinfo);
}
} else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
cconvert->pub.color_convert = gray_rgb_convert;
} else if (cinfo->jpeg_color_space == cinfo->out_color_space &&
rgb_pixelsize[cinfo->out_color_space] == 3) {
cconvert->pub.color_convert = null_convert;
} else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);

16
jdct.h
View File

@@ -23,18 +23,26 @@
* have a range of +-8K for 8-bit data, +-128K for 12-bit data. This
* convention improves accuracy in integer implementations and saves some
* work in floating-point ones.
* Quantization of the output coefficients is done by jcdctmgr.c.
* Quantization of the output coefficients is done by jcdctmgr.c. This
* step requires an unsigned type and also one with twice the bits.
*/
#if BITS_IN_JSAMPLE == 8
#ifndef WITH_SIMD
typedef int DCTELEM; /* 16 or 32 bits is fine */
typedef unsigned int UDCTELEM;
typedef unsigned long long UDCTELEM2;
#else
typedef short DCTELEM; /* prefer 16 bit with SIMD for parellelism */
typedef unsigned short UDCTELEM;
typedef unsigned int UDCTELEM2;
#endif
#else
typedef INT32 DCTELEM; /* must have 32 bits */
typedef UINT32 UDCTELEM;
typedef unsigned long long UDCTELEM2;
#endif
typedef JMETHOD(void, forward_DCT_method_ptr, (DCTELEM * data));
typedef JMETHOD(void, float_DCT_method_ptr, (FAST_FLOAT * data));
/*
* An inverse DCT routine is given a pointer to the input JBLOCK and a pointer

View File

@@ -2,6 +2,8 @@
* jddctmgr.c
*
* Copyright (C) 1994-1996, Thomas G. Lane.
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
* Copyright (C) 2010, 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.
*
@@ -19,6 +21,8 @@
#include "jinclude.h"
#include "jpeglib.h"
#include "jdct.h" /* Private declarations for DCT subsystem */
#include "jsimddct.h"
#include "jpegcomp.h"
/*
@@ -98,18 +102,24 @@ start_pass (j_decompress_ptr cinfo)
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
/* Select the proper IDCT routine for this component's scaling */
switch (compptr->DCT_scaled_size) {
switch (compptr->_DCT_scaled_size) {
#ifdef IDCT_SCALING_SUPPORTED
case 1:
method_ptr = jpeg_idct_1x1;
method = JDCT_ISLOW; /* jidctred uses islow-style table */
break;
case 2:
method_ptr = jpeg_idct_2x2;
if (jsimd_can_idct_2x2())
method_ptr = jsimd_idct_2x2;
else
method_ptr = jpeg_idct_2x2;
method = JDCT_ISLOW; /* jidctred uses islow-style table */
break;
case 4:
method_ptr = jpeg_idct_4x4;
if (jsimd_can_idct_4x4())
method_ptr = jsimd_idct_4x4;
else
method_ptr = jpeg_idct_4x4;
method = JDCT_ISLOW; /* jidctred uses islow-style table */
break;
#endif
@@ -117,19 +127,28 @@ start_pass (j_decompress_ptr cinfo)
switch (cinfo->dct_method) {
#ifdef DCT_ISLOW_SUPPORTED
case JDCT_ISLOW:
method_ptr = jpeg_idct_islow;
if (jsimd_can_idct_islow())
method_ptr = jsimd_idct_islow;
else
method_ptr = jpeg_idct_islow;
method = JDCT_ISLOW;
break;
#endif
#ifdef DCT_IFAST_SUPPORTED
case JDCT_IFAST:
method_ptr = jpeg_idct_ifast;
if (jsimd_can_idct_ifast())
method_ptr = jsimd_idct_ifast;
else
method_ptr = jpeg_idct_ifast;
method = JDCT_IFAST;
break;
#endif
#ifdef DCT_FLOAT_SUPPORTED
case JDCT_FLOAT:
method_ptr = jpeg_idct_float;
if (jsimd_can_idct_float())
method_ptr = jsimd_idct_float;
else
method_ptr = jpeg_idct_float;
method = JDCT_FLOAT;
break;
#endif
@@ -139,7 +158,7 @@ start_pass (j_decompress_ptr cinfo)
}
break;
default:
ERREXIT1(cinfo, JERR_BAD_DCTSIZE, compptr->DCT_scaled_size);
ERREXIT1(cinfo, JERR_BAD_DCTSIZE, compptr->_DCT_scaled_size);
break;
}
idct->pub.inverse_DCT[ci] = method_ptr;

600
jdhuff.c
View File

@@ -1,7 +1,8 @@
/*
* jdhuff.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Copyright (C) 1991-1997, Thomas G. Lane.
* Copyright (C) 2010, 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.
*
@@ -14,10 +15,26 @@
* storage only upon successful completion of an MCU.
*/
/* Performance enhancements:
* Copyright (C)2007 Sun Microsystems, Inc.
* Copyright (C)2009-2010 D. R. Commander
*
* This library is free software and may be redistributed and/or modified under
* the terms of the wxWindows Library License, Version 3.1 or (at your option)
* any later version. The full license is in the LICENSE.txt file included
* with this distribution.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* wxWindows Library License for more details.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jdhuff.h" /* Declarations shared with jdphuff.c */
#include "jpegcomp.h"
/*
@@ -64,6 +81,15 @@ typedef struct {
/* Pointers to derived tables (these workspaces have image lifespan) */
d_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS];
d_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS];
/* Precalculated info set up by start_pass for use in decode_mcu: */
/* Pointers to derived tables to be used for each block within an MCU */
d_derived_tbl * dc_cur_tbls[D_MAX_BLOCKS_IN_MCU];
d_derived_tbl * ac_cur_tbls[D_MAX_BLOCKS_IN_MCU];
/* Whether we care about the DC and AC coefficient values for each block */
boolean dc_needed[D_MAX_BLOCKS_IN_MCU];
boolean ac_needed[D_MAX_BLOCKS_IN_MCU];
} huff_entropy_decoder;
typedef huff_entropy_decoder * huff_entropy_ptr;
@@ -77,7 +103,7 @@ METHODDEF(void)
start_pass_huff_decoder (j_decompress_ptr cinfo)
{
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
int ci, dctbl, actbl;
int ci, blkn, dctbl, actbl;
jpeg_component_info * compptr;
/* Check that the scan parameters Ss, Se, Ah/Al are OK for sequential JPEG.
@@ -92,27 +118,37 @@ start_pass_huff_decoder (j_decompress_ptr cinfo)
compptr = cinfo->cur_comp_info[ci];
dctbl = compptr->dc_tbl_no;
actbl = compptr->ac_tbl_no;
/* Make sure requested tables are present */
if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS ||
cinfo->dc_huff_tbl_ptrs[dctbl] == NULL)
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl);
if (actbl < 0 || actbl >= NUM_HUFF_TBLS ||
cinfo->ac_huff_tbl_ptrs[actbl] == NULL)
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, actbl);
/* Compute derived values for Huffman tables */
/* We may do this more than once for a table, but it's not expensive */
jpeg_make_d_derived_tbl(cinfo, cinfo->dc_huff_tbl_ptrs[dctbl],
jpeg_make_d_derived_tbl(cinfo, TRUE, dctbl,
& entropy->dc_derived_tbls[dctbl]);
jpeg_make_d_derived_tbl(cinfo, cinfo->ac_huff_tbl_ptrs[actbl],
jpeg_make_d_derived_tbl(cinfo, FALSE, actbl,
& entropy->ac_derived_tbls[actbl]);
/* Initialize DC predictions to 0 */
entropy->saved.last_dc_val[ci] = 0;
}
/* Precalculate decoding info for each block in an MCU of this scan */
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
ci = cinfo->MCU_membership[blkn];
compptr = cinfo->cur_comp_info[ci];
/* Precalculate which table to use for each block */
entropy->dc_cur_tbls[blkn] = entropy->dc_derived_tbls[compptr->dc_tbl_no];
entropy->ac_cur_tbls[blkn] = entropy->ac_derived_tbls[compptr->ac_tbl_no];
/* Decide whether we really care about the coefficient values */
if (compptr->component_needed) {
entropy->dc_needed[blkn] = TRUE;
/* we don't need the ACs if producing a 1/8th-size image */
entropy->ac_needed[blkn] = (compptr->_DCT_scaled_size > 1);
} else {
entropy->dc_needed[blkn] = entropy->ac_needed[blkn] = FALSE;
}
}
/* Initialize bitread state variables */
entropy->bitstate.bits_left = 0;
entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */
entropy->bitstate.printed_eod = FALSE;
entropy->pub.insufficient_data = FALSE;
/* Initialize restart counter */
entropy->restarts_to_go = cinfo->restart_interval;
@@ -121,20 +157,35 @@ start_pass_huff_decoder (j_decompress_ptr cinfo)
/*
* Compute the derived values for a Huffman table.
* This routine also performs some validation checks on the table.
*
* Note this is also used by jdphuff.c.
*/
GLOBAL(void)
jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, JHUFF_TBL * htbl,
jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, boolean isDC, int tblno,
d_derived_tbl ** pdtbl)
{
JHUFF_TBL *htbl;
d_derived_tbl *dtbl;
int p, i, l, si;
int p, i, l, si, numsymbols;
int lookbits, ctr;
char huffsize[257];
unsigned int huffcode[257];
unsigned int code;
/* Note that huffsize[] and huffcode[] are filled in code-length order,
* paralleling the order of the symbols themselves in htbl->huffval[].
*/
/* Find the input Huffman table */
if (tblno < 0 || tblno >= NUM_HUFF_TBLS)
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
htbl =
isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno];
if (htbl == NULL)
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
/* Allocate a workspace if we haven't already done so. */
if (*pdtbl == NULL)
*pdtbl = (d_derived_tbl *)
@@ -144,17 +195,20 @@ jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, JHUFF_TBL * htbl,
dtbl->pub = htbl; /* fill in back link */
/* Figure C.1: make table of Huffman code length for each symbol */
/* Note that this is in code-length order. */
p = 0;
for (l = 1; l <= 16; l++) {
for (i = 1; i <= (int) htbl->bits[l]; i++)
i = (int) htbl->bits[l];
if (i < 0 || p + i > 256) /* protect against table overrun */
ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
while (i--)
huffsize[p++] = (char) l;
}
huffsize[p] = 0;
numsymbols = p;
/* Figure C.2: generate the codes themselves */
/* Note that this is in code-length order. */
/* We also validate that the counts represent a legal Huffman code tree. */
code = 0;
si = huffsize[0];
@@ -164,6 +218,11 @@ jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, JHUFF_TBL * htbl,
huffcode[p++] = code;
code++;
}
/* code is now 1 more than the last code used for codelength si; but
* it must still fit in si bits, since no code is allowed to be all ones.
*/
if (((INT32) code) >= (((INT32) 1) << si))
ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
code <<= 1;
si++;
}
@@ -173,14 +232,17 @@ jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, JHUFF_TBL * htbl,
p = 0;
for (l = 1; l <= 16; l++) {
if (htbl->bits[l]) {
dtbl->valptr[l] = p; /* huffval[] index of 1st symbol of code length l */
dtbl->mincode[l] = huffcode[p]; /* minimum code of length l */
/* valoffset[l] = huffval[] index of 1st symbol of code length l,
* minus the minimum code of length l
*/
dtbl->valoffset[l] = (INT32) p - (INT32) huffcode[p];
p += htbl->bits[l];
dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */
} else {
dtbl->maxcode[l] = -1; /* -1 if no codes of this length */
}
}
dtbl->valoffset[17] = 0;
dtbl->maxcode[17] = 0xFFFFFL; /* ensures jpeg_huff_decode terminates */
/* Compute lookahead tables to speed up decoding.
@@ -190,7 +252,8 @@ jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, JHUFF_TBL * htbl,
* with that code.
*/
MEMZERO(dtbl->look_nbits, SIZEOF(dtbl->look_nbits));
for (i = 0; i < (1 << HUFF_LOOKAHEAD); i++)
dtbl->lookup[i] = (HUFF_LOOKAHEAD + 1) << HUFF_LOOKAHEAD;
p = 0;
for (l = 1; l <= HUFF_LOOKAHEAD; l++) {
@@ -199,12 +262,25 @@ jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, JHUFF_TBL * htbl,
/* Generate left-justified code followed by all possible bit sequences */
lookbits = huffcode[p] << (HUFF_LOOKAHEAD-l);
for (ctr = 1 << (HUFF_LOOKAHEAD-l); ctr > 0; ctr--) {
dtbl->look_nbits[lookbits] = l;
dtbl->look_sym[lookbits] = htbl->huffval[p];
dtbl->lookup[lookbits] = (l << HUFF_LOOKAHEAD) | htbl->huffval[p];
lookbits++;
}
}
}
/* Validate symbols as being reasonable.
* For AC tables, we make no check, but accept all byte values 0..255.
* For DC tables, we require the symbols to be in range 0..15.
* (Tighter bounds could be applied depending on the data depth and mode,
* but this is sufficient to ensure safe decoding.)
*/
if (isDC) {
for (i = 0; i < numsymbols; i++) {
int sym = htbl->huffval[i];
if (sym < 0 || sym > 15)
ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
}
}
}
@@ -239,68 +315,86 @@ jpeg_fill_bit_buffer (bitread_working_state * state,
/* Copy heavily used state fields into locals (hopefully registers) */
register const JOCTET * next_input_byte = state->next_input_byte;
register size_t bytes_in_buffer = state->bytes_in_buffer;
register int c;
j_decompress_ptr cinfo = state->cinfo;
/* Attempt to load at least MIN_GET_BITS bits into get_buffer. */
/* (It is assumed that no request will be for more than that many bits.) */
/* We fail to do so only if we hit a marker or are forced to suspend. */
while (bits_left < MIN_GET_BITS) {
/* Attempt to read a byte */
if (state->unread_marker != 0)
goto no_more_data; /* can't advance past a marker */
if (cinfo->unread_marker == 0) { /* cannot advance past a marker */
while (bits_left < MIN_GET_BITS) {
register int c;
if (bytes_in_buffer == 0) {
if (! (*state->cinfo->src->fill_input_buffer) (state->cinfo))
return FALSE;
next_input_byte = state->cinfo->src->next_input_byte;
bytes_in_buffer = state->cinfo->src->bytes_in_buffer;
}
bytes_in_buffer--;
c = GETJOCTET(*next_input_byte++);
/* If it's 0xFF, check and discard stuffed zero byte */
if (c == 0xFF) {
do {
if (bytes_in_buffer == 0) {
if (! (*state->cinfo->src->fill_input_buffer) (state->cinfo))
return FALSE;
next_input_byte = state->cinfo->src->next_input_byte;
bytes_in_buffer = state->cinfo->src->bytes_in_buffer;
}
bytes_in_buffer--;
c = GETJOCTET(*next_input_byte++);
} while (c == 0xFF);
if (c == 0) {
/* Found FF/00, which represents an FF data byte */
c = 0xFF;
} else {
/* Oops, it's actually a marker indicating end of compressed data. */
/* Better put it back for use later */
state->unread_marker = c;
no_more_data:
/* There should be enough bits still left in the data segment; */
/* if so, just break out of the outer while loop. */
if (bits_left >= nbits)
break;
/* Uh-oh. Report corrupted data to user and stuff zeroes into
* the data stream, so that we can produce some kind of image.
* Note that this code will be repeated for each byte demanded
* for the rest of the segment. We use a nonvolatile flag to ensure
* that only one warning message appears.
*/
if (! *(state->printed_eod_ptr)) {
WARNMS(state->cinfo, JWRN_HIT_MARKER);
*(state->printed_eod_ptr) = TRUE;
}
c = 0; /* insert a zero byte into bit buffer */
/* Attempt to read a byte */
if (bytes_in_buffer == 0) {
if (! (*cinfo->src->fill_input_buffer) (cinfo))
return FALSE;
next_input_byte = cinfo->src->next_input_byte;
bytes_in_buffer = cinfo->src->bytes_in_buffer;
}
}
bytes_in_buffer--;
c = GETJOCTET(*next_input_byte++);
/* OK, load c into get_buffer */
get_buffer = (get_buffer << 8) | c;
bits_left += 8;
/* If it's 0xFF, check and discard stuffed zero byte */
if (c == 0xFF) {
/* Loop here to discard any padding FF's on terminating marker,
* so that we can save a valid unread_marker value. NOTE: we will
* accept multiple FF's followed by a 0 as meaning a single FF data
* byte. This data pattern is not valid according to the standard.
*/
do {
if (bytes_in_buffer == 0) {
if (! (*cinfo->src->fill_input_buffer) (cinfo))
return FALSE;
next_input_byte = cinfo->src->next_input_byte;
bytes_in_buffer = cinfo->src->bytes_in_buffer;
}
bytes_in_buffer--;
c = GETJOCTET(*next_input_byte++);
} while (c == 0xFF);
if (c == 0) {
/* Found FF/00, which represents an FF data byte */
c = 0xFF;
} else {
/* Oops, it's actually a marker indicating end of compressed data.
* Save the marker code for later use.
* Fine point: it might appear that we should save the marker into
* bitread working state, not straight into permanent state. But
* once we have hit a marker, we cannot need to suspend within the
* current MCU, because we will read no more bytes from the data
* source. So it is OK to update permanent state right away.
*/
cinfo->unread_marker = c;
/* See if we need to insert some fake zero bits. */
goto no_more_bytes;
}
}
/* OK, load c into get_buffer */
get_buffer = (get_buffer << 8) | c;
bits_left += 8;
} /* end while */
} else {
no_more_bytes:
/* We get here if we've read the marker that terminates the compressed
* data segment. There should be enough bits in the buffer register
* to satisfy the request; if so, no problem.
*/
if (nbits > bits_left) {
/* Uh-oh. Report corrupted data to user and stuff zeroes into
* the data stream, so that we can produce some kind of image.
* We use a nonvolatile flag to ensure that only one warning message
* appears per data segment.
*/
if (! cinfo->entropy->insufficient_data) {
WARNMS(cinfo, JWRN_HIT_MARKER);
cinfo->entropy->insufficient_data = TRUE;
}
/* Fill the buffer with zero bits */
get_buffer <<= MIN_GET_BITS - bits_left;
bits_left = MIN_GET_BITS;
}
}
/* Unload the local registers */
@@ -353,8 +447,7 @@ jpeg_huff_decode (bitread_working_state * state,
return 0; /* fake a zero as the safest result */
}
return htbl->pub->huffval[ htbl->valptr[l] +
((int) (code - htbl->mincode[l])) ];
return htbl->pub->huffval[ (int) (code + htbl->valoffset[l]) ];
}
@@ -363,9 +456,10 @@ jpeg_huff_decode (bitread_working_state * state,
* On some machines, a shift and add will be faster than a table lookup.
*/
#define AVOID_TABLES
#ifdef AVOID_TABLES
#define HUFF_EXTEND(x,s) ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x))
#define HUFF_EXTEND(x,s) ((x) + ((((x) - (1<<((s)-1))) >> 31) & (((-1)<<(s)) + 1)))
#else
@@ -411,13 +505,248 @@ process_restart (j_decompress_ptr cinfo)
/* Reset restart counter */
entropy->restarts_to_go = cinfo->restart_interval;
/* Next segment can get another out-of-data warning */
entropy->bitstate.printed_eod = FALSE;
/* Reset out-of-data flag, unless read_restart_marker left us smack up
* against a marker. In that case we will end up treating the next data
* segment as empty, and we can avoid producing bogus output pixels by
* leaving the flag set.
*/
if (cinfo->unread_marker == 0)
entropy->pub.insufficient_data = FALSE;
return TRUE;
}
LOCAL(boolean)
decode_mcu_slow (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
BITREAD_STATE_VARS;
int blkn;
savable_state state;
/* Outer loop handles each block in the MCU */
/* Load up working state */
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
ASSIGN_STATE(state, entropy->saved);
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
JBLOCKROW block = MCU_data[blkn];
d_derived_tbl * dctbl = entropy->dc_cur_tbls[blkn];
d_derived_tbl * actbl = entropy->ac_cur_tbls[blkn];
register int s, k, r;
/* Decode a single block's worth of coefficients */
/* Section F.2.2.1: decode the DC coefficient difference */
HUFF_DECODE(s, br_state, dctbl, return FALSE, label1);
if (s) {
CHECK_BIT_BUFFER(br_state, s, return FALSE);
r = GET_BITS(s);
s = HUFF_EXTEND(r, s);
}
if (entropy->dc_needed[blkn]) {
/* Convert DC difference to actual value, update last_dc_val */
int ci = cinfo->MCU_membership[blkn];
s += state.last_dc_val[ci];
state.last_dc_val[ci] = s;
/* Output the DC coefficient (assumes jpeg_natural_order[0] = 0) */
(*block)[0] = (JCOEF) s;
}
if (entropy->ac_needed[blkn]) {
/* Section F.2.2.2: decode the AC coefficients */
/* Since zeroes are skipped, output area must be cleared beforehand */
for (k = 1; k < DCTSIZE2; k++) {
HUFF_DECODE(s, br_state, actbl, return FALSE, label2);
r = s >> 4;
s &= 15;
if (s) {
k += r;
CHECK_BIT_BUFFER(br_state, s, return FALSE);
r = GET_BITS(s);
s = HUFF_EXTEND(r, s);
/* Output coefficient in natural (dezigzagged) order.
* Note: the extra entries in jpeg_natural_order[] will save us
* if k >= DCTSIZE2, which could happen if the data is corrupted.
*/
(*block)[jpeg_natural_order[k]] = (JCOEF) s;
} else {
if (r != 15)
break;
k += 15;
}
}
} else {
/* Section F.2.2.2: decode the AC coefficients */
/* In this path we just discard the values */
for (k = 1; k < DCTSIZE2; k++) {
HUFF_DECODE(s, br_state, actbl, return FALSE, label3);
r = s >> 4;
s &= 15;
if (s) {
k += r;
CHECK_BIT_BUFFER(br_state, s, return FALSE);
DROP_BITS(s);
} else {
if (r != 15)
break;
k += 15;
}
}
}
}
/* Completed MCU, so update state */
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
ASSIGN_STATE(entropy->saved, state);
return TRUE;
}
/***************************************************************/
#define ADD_BYTE { \
int val0 = *(buffer++); \
int val1 = *(buffer); \
\
bits_left += 8; \
get_buffer = (get_buffer << 8) | (val0); \
if (val0 == 0xFF) { \
buffer++; \
if (val1 != 0) { \
buffer -= 2; \
get_buffer &= ~0xFF; \
} \
} \
}
/***************************************************************/
#if __WORDSIZE == 64 || defined(_WIN64)
#define ENSURE_SHORT \
if (bits_left < 16) { \
ADD_BYTE ADD_BYTE ADD_BYTE ADD_BYTE ADD_BYTE ADD_BYTE \
}
#else
#define ENSURE_SHORT if (bits_left < 16) { ADD_BYTE ADD_BYTE }
#endif
/***************************************************************/
#define HUFF_DECODE_FAST(symbol, size, htbl) { \
ENSURE_SHORT \
symbol = PEEK_BITS(HUFF_LOOKAHEAD); \
symbol = htbl->lookup[symbol]; \
size = symbol >> 8; \
bits_left -= size; \
symbol = symbol & ((1 << HUFF_LOOKAHEAD) - 1); \
if (size == HUFF_LOOKAHEAD + 1) { \
symbol = (get_buffer >> bits_left) & ((1 << (size)) - 1); \
while (symbol > htbl->maxcode[size]) { \
symbol <<= 1; \
symbol |= GET_BITS(1); \
size++; \
} \
symbol = htbl->pub->huffval[ (int) (symbol + htbl->valoffset[size]) & 0xFF ]; \
} \
}
/***************************************************************/
LOCAL(boolean)
decode_mcu_fast (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
BITREAD_STATE_VARS;
JOCTET *buffer;
int blkn;
savable_state state;
/* Outer loop handles each block in the MCU */
/* Load up working state */
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
buffer = (JOCTET *) br_state.next_input_byte;
ASSIGN_STATE(state, entropy->saved);
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
JBLOCKROW block = MCU_data[blkn];
d_derived_tbl * dctbl = entropy->dc_cur_tbls[blkn];
d_derived_tbl * actbl = entropy->ac_cur_tbls[blkn];
register int s, k, r, l;
HUFF_DECODE_FAST(s, l, dctbl);
if (s) {
ENSURE_SHORT
r = GET_BITS(s);
s = HUFF_EXTEND(r, s);
}
if (entropy->dc_needed[blkn]) {
int ci = cinfo->MCU_membership[blkn];
s += state.last_dc_val[ci];
state.last_dc_val[ci] = s;
(*block)[0] = (JCOEF) s;
}
if (entropy->ac_needed[blkn]) {
for (k = 1; k < DCTSIZE2; k++) {
HUFF_DECODE_FAST(s, l, actbl);
r = s >> 4;
s &= 15;
if (s) {
k += r;
ENSURE_SHORT
r = GET_BITS(s);
s = HUFF_EXTEND(r, s);
(*block)[jpeg_natural_order[k]] = (JCOEF) s;
} else {
if (r != 15) break;
k += 15;
}
}
} else {
for (k = 1; k < DCTSIZE2; k++) {
HUFF_DECODE_FAST(s, l, actbl);
r = s >> 4;
s &= 15;
if (s) {
k += r;
ENSURE_SHORT
DROP_BITS(s);
} else {
if (r != 15) break;
k += 15;
}
}
}
}
br_state.bytes_in_buffer -= (buffer - br_state.next_input_byte);
br_state.next_input_byte = buffer;
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
ASSIGN_STATE(entropy->saved, state);
return TRUE;
}
/*
* Decode and return one MCU's worth of Huffman-compressed coefficients.
* The coefficients are reordered from zigzag order into natural array order,
@@ -433,116 +762,39 @@ process_restart (j_decompress_ptr cinfo)
* this module, since we'll just re-assign them on the next call.)
*/
#define BUFSIZE (DCTSIZE2 * 2)
METHODDEF(boolean)
decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
register int s, k, r;
int blkn, ci;
JBLOCKROW block;
BITREAD_STATE_VARS;
savable_state state;
d_derived_tbl * dctbl;
d_derived_tbl * actbl;
jpeg_component_info * compptr;
int usefast = 1;
/* Process restart marker if needed; may have to suspend */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0)
if (! process_restart(cinfo))
return FALSE;
usefast = 0;
}
/* Load up working state */
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
ASSIGN_STATE(state, entropy->saved);
if (cinfo->src->bytes_in_buffer < BUFSIZE * cinfo->blocks_in_MCU)
usefast = 0;
/* Outer loop handles each block in the MCU */
/* If we've run out of data, just leave the MCU set to zeroes.
* This way, we return uniform gray for the remainder of the segment.
*/
if (! entropy->pub.insufficient_data) {
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
block = MCU_data[blkn];
ci = cinfo->MCU_membership[blkn];
compptr = cinfo->cur_comp_info[ci];
dctbl = entropy->dc_derived_tbls[compptr->dc_tbl_no];
actbl = entropy->ac_derived_tbls[compptr->ac_tbl_no];
/* Decode a single block's worth of coefficients */
/* Section F.2.2.1: decode the DC coefficient difference */
HUFF_DECODE(s, br_state, dctbl, return FALSE, label1);
if (s) {
CHECK_BIT_BUFFER(br_state, s, return FALSE);
r = GET_BITS(s);
s = HUFF_EXTEND(r, s);
if (usefast) {
if (!decode_mcu_fast(cinfo, MCU_data)) return FALSE;
}
else {
if (!decode_mcu_slow(cinfo, MCU_data)) return FALSE;
}
/* Shortcut if component's values are not interesting */
if (! compptr->component_needed)
goto skip_ACs;
/* Convert DC difference to actual value, update last_dc_val */
s += state.last_dc_val[ci];
state.last_dc_val[ci] = s;
/* Output the DC coefficient (assumes jpeg_natural_order[0] = 0) */
(*block)[0] = (JCOEF) s;
/* Do we need to decode the AC coefficients for this component? */
if (compptr->DCT_scaled_size > 1) {
/* Section F.2.2.2: decode the AC coefficients */
/* Since zeroes are skipped, output area must be cleared beforehand */
for (k = 1; k < DCTSIZE2; k++) {
HUFF_DECODE(s, br_state, actbl, return FALSE, label2);
r = s >> 4;
s &= 15;
if (s) {
k += r;
CHECK_BIT_BUFFER(br_state, s, return FALSE);
r = GET_BITS(s);
s = HUFF_EXTEND(r, s);
/* Output coefficient in natural (dezigzagged) order.
* Note: the extra entries in jpeg_natural_order[] will save us
* if k >= DCTSIZE2, which could happen if the data is corrupted.
*/
(*block)[jpeg_natural_order[k]] = (JCOEF) s;
} else {
if (r != 15)
break;
k += 15;
}
}
} else {
skip_ACs:
/* Section F.2.2.2: decode the AC coefficients */
/* In this path we just discard the values */
for (k = 1; k < DCTSIZE2; k++) {
HUFF_DECODE(s, br_state, actbl, return FALSE, label3);
r = s >> 4;
s &= 15;
if (s) {
k += r;
CHECK_BIT_BUFFER(br_state, s, return FALSE);
DROP_BITS(s);
} else {
if (r != 15)
break;
k += 15;
}
}
}
}
/* Completed MCU, so update state */
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
ASSIGN_STATE(entropy->saved, state);
/* Account for restart interval (no-op if not using restarts) */
entropy->restarts_to_go--;

View File

@@ -1,7 +1,8 @@
/*
* jdhuff.h
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Copyright (C) 1991-1997, Thomas G. Lane.
* Copyright (C) 2010, 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.
*
@@ -25,26 +26,34 @@
typedef struct {
/* Basic tables: (element [0] of each array is unused) */
INT32 mincode[17]; /* smallest code of length k */
INT32 maxcode[18]; /* largest code of length k (-1 if none) */
/* (maxcode[17] is a sentinel to ensure jpeg_huff_decode terminates) */
int valptr[17]; /* huffval[] index of 1st symbol of length k */
INT32 valoffset[18]; /* huffval[] offset for codes of length k */
/* valoffset[k] = huffval[] index of 1st symbol of code length k, less
* the smallest code of length k; so given a code of length k, the
* corresponding symbol is huffval[code + valoffset[k]]
*/
/* Link to public Huffman table (needed only in jpeg_huff_decode) */
JHUFF_TBL *pub;
/* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of
/* Lookahead table: indexed by the next HUFF_LOOKAHEAD bits of
* the input data stream. If the next Huffman code is no more
* than HUFF_LOOKAHEAD bits long, we can obtain its length and
* the corresponding symbol directly from these tables.
* the corresponding symbol directly from this tables.
*
* The lower 8 bits of each table entry contain the number of
* bits in the corresponding Huffman code, or HUFF_LOOKAHEAD + 1
* if too long. The next 8 bits of each entry contain the
* symbol.
*/
int look_nbits[1<<HUFF_LOOKAHEAD]; /* # bits, or 0 if too long */
UINT8 look_sym[1<<HUFF_LOOKAHEAD]; /* symbol, or unused */
int lookup[1<<HUFF_LOOKAHEAD];
} d_derived_tbl;
/* Expand a Huffman table definition into the derived format */
EXTERN(void) jpeg_make_d_derived_tbl JPP((j_decompress_ptr cinfo,
JHUFF_TBL * htbl, d_derived_tbl ** pdtbl));
EXTERN(void) jpeg_make_d_derived_tbl
JPP((j_decompress_ptr cinfo, boolean isDC, int tblno,
d_derived_tbl ** pdtbl));
/*
@@ -65,35 +74,42 @@ EXTERN(void) jpeg_make_d_derived_tbl JPP((j_decompress_ptr cinfo,
* necessary.
*/
#if __WORDSIZE == 64 || defined(_WIN64)
typedef size_t bit_buf_type; /* type of bit-extraction buffer */
#define BIT_BUF_SIZE 64 /* size of buffer in bits */
#else
typedef INT32 bit_buf_type; /* type of bit-extraction buffer */
#define BIT_BUF_SIZE 32 /* size of buffer in bits */
#define BIT_BUF_SIZE 32 /* size of buffer in bits */
#endif
/* If long is > 32 bits on your machine, and shifting/masking longs is
* reasonably fast, making bit_buf_type be long and setting BIT_BUF_SIZE
* appropriately should be a win. Unfortunately we can't do this with
* something like #define BIT_BUF_SIZE (sizeof(bit_buf_type)*8)
* appropriately should be a win. Unfortunately we can't define the size
* with something like #define BIT_BUF_SIZE (sizeof(bit_buf_type)*8)
* because not all machines measure sizeof in 8-bit bytes.
*/
typedef struct { /* Bitreading state saved across MCUs */
bit_buf_type get_buffer; /* current bit-extraction buffer */
int bits_left; /* # of unused bits in it */
boolean printed_eod; /* flag to suppress multiple warning msgs */
} bitread_perm_state;
typedef struct { /* Bitreading working state within an MCU */
/* current data source state */
/* Current data source location */
/* We need a copy, rather than munging the original, in case of suspension */
const JOCTET * next_input_byte; /* => next byte to read from source */
size_t bytes_in_buffer; /* # of bytes remaining in source buffer */
int unread_marker; /* nonzero if we have hit a marker */
/* bit input buffer --- note these values are kept in register variables,
/* Bit input buffer --- note these values are kept in register variables,
* not in this struct, inside the inner loops.
*/
bit_buf_type get_buffer; /* current bit-extraction buffer */
int bits_left; /* # of unused bits in it */
/* pointers needed by jpeg_fill_bit_buffer */
/* Pointer needed by jpeg_fill_bit_buffer. */
j_decompress_ptr cinfo; /* back link to decompress master record */
boolean * printed_eod_ptr; /* => flag in permanent state */
} bitread_working_state;
/* Macros to declare and load/save bitread local variables. */
@@ -106,15 +122,12 @@ typedef struct { /* Bitreading working state within an MCU */
br_state.cinfo = cinfop; \
br_state.next_input_byte = cinfop->src->next_input_byte; \
br_state.bytes_in_buffer = cinfop->src->bytes_in_buffer; \
br_state.unread_marker = cinfop->unread_marker; \
get_buffer = permstate.get_buffer; \
bits_left = permstate.bits_left; \
br_state.printed_eod_ptr = & permstate.printed_eod
bits_left = permstate.bits_left;
#define BITREAD_SAVE_STATE(cinfop,permstate) \
cinfop->src->next_input_byte = br_state.next_input_byte; \
cinfop->src->bytes_in_buffer = br_state.bytes_in_buffer; \
cinfop->unread_marker = br_state.unread_marker; \
permstate.get_buffer = get_buffer; \
permstate.bits_left = bits_left
@@ -184,11 +197,10 @@ EXTERN(boolean) jpeg_fill_bit_buffer
} \
} \
look = PEEK_BITS(HUFF_LOOKAHEAD); \
if ((nb = htbl->look_nbits[look]) != 0) { \
if ((nb = (htbl->lookup[look] >> HUFF_LOOKAHEAD)) <= HUFF_LOOKAHEAD) { \
DROP_BITS(nb); \
result = htbl->look_sym[look]; \
result = htbl->lookup[look] & ((1 << HUFF_LOOKAHEAD) - 1); \
} else { \
nb = HUFF_LOOKAHEAD+1; \
slowlabel: \
if ((result=jpeg_huff_decode(&state,get_buffer,bits_left,htbl,nb)) < 0) \
{ failaction; } \

View File

@@ -1,7 +1,9 @@
/*
* jdinput.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2002-2009 by Guido Vollbeding.
* Copyright (C) 2010, 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.
*
@@ -14,6 +16,7 @@
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jpegcomp.h"
/* Private state */
@@ -35,6 +38,79 @@ METHODDEF(int) consume_markers JPP((j_decompress_ptr cinfo));
* Routines to calculate various quantities related to the size of the image.
*/
#if JPEG_LIB_VERSION >= 80
/*
* Compute output image dimensions and related values.
* NOTE: this is exported for possible use by application.
* Hence it mustn't do anything that can't be done twice.
*/
GLOBAL(void)
jpeg_core_output_dimensions (j_decompress_ptr cinfo)
/* Do computations that are needed before master selection phase.
* This function is used for transcoding and full decompression.
*/
{
#ifdef IDCT_SCALING_SUPPORTED
int ci;
jpeg_component_info *compptr;
/* Compute actual output image dimensions and DCT scaling choices. */
if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom) {
/* Provide 1/block_size scaling */
cinfo->output_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width, (long) cinfo->block_size);
cinfo->output_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height, (long) cinfo->block_size);
cinfo->min_DCT_h_scaled_size = 1;
cinfo->min_DCT_v_scaled_size = 1;
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 2) {
/* Provide 2/block_size scaling */
cinfo->output_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * 2L, (long) cinfo->block_size);
cinfo->output_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * 2L, (long) cinfo->block_size);
cinfo->min_DCT_h_scaled_size = 2;
cinfo->min_DCT_v_scaled_size = 2;
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 4) {
/* Provide 4/block_size scaling */
cinfo->output_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * 4L, (long) cinfo->block_size);
cinfo->output_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * 4L, (long) cinfo->block_size);
cinfo->min_DCT_h_scaled_size = 4;
cinfo->min_DCT_v_scaled_size = 4;
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 8) {
/* Provide 8/block_size scaling */
cinfo->output_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * 8L, (long) cinfo->block_size);
cinfo->output_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * 8L, (long) cinfo->block_size);
cinfo->min_DCT_h_scaled_size = 8;
cinfo->min_DCT_v_scaled_size = 8;
}
/* Recompute dimensions of components */
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
compptr->DCT_h_scaled_size = cinfo->min_DCT_h_scaled_size;
compptr->DCT_v_scaled_size = cinfo->min_DCT_v_scaled_size;
}
#else /* !IDCT_SCALING_SUPPORTED */
/* Hardwire it to "no scaling" */
cinfo->output_width = cinfo->image_width;
cinfo->output_height = cinfo->image_height;
/* jdinput.c has already initialized DCT_scaled_size,
* and has computed unscaled downsampled_width and downsampled_height.
*/
#endif /* IDCT_SCALING_SUPPORTED */
}
#endif
LOCAL(void)
initial_setup (j_decompress_ptr cinfo)
/* Called once, when first SOS marker is reached */
@@ -70,16 +146,30 @@ initial_setup (j_decompress_ptr cinfo)
compptr->v_samp_factor);
}
#if JPEG_LIB_VERSION >=80
cinfo->block_size = DCTSIZE;
cinfo->natural_order = jpeg_natural_order;
cinfo->lim_Se = DCTSIZE2-1;
#endif
/* We initialize DCT_scaled_size and min_DCT_scaled_size to DCTSIZE.
* In the full decompressor, this will be overridden by jdmaster.c;
* but in the transcoder, jdmaster.c is not used, so we must do it here.
*/
#if JPEG_LIB_VERSION >= 70
cinfo->min_DCT_h_scaled_size = cinfo->min_DCT_v_scaled_size = DCTSIZE;
#else
cinfo->min_DCT_scaled_size = DCTSIZE;
#endif
/* Compute dimensions of components */
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
#if JPEG_LIB_VERSION >= 70
compptr->DCT_h_scaled_size = compptr->DCT_v_scaled_size = DCTSIZE;
#else
compptr->DCT_scaled_size = DCTSIZE;
#endif
/* Size in DCT blocks */
compptr->width_in_blocks = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
@@ -138,7 +228,7 @@ per_scan_setup (j_decompress_ptr cinfo)
compptr->MCU_width = 1;
compptr->MCU_height = 1;
compptr->MCU_blocks = 1;
compptr->MCU_sample_width = compptr->DCT_scaled_size;
compptr->MCU_sample_width = compptr->_DCT_scaled_size;
compptr->last_col_width = 1;
/* For noninterleaved scans, it is convenient to define last_row_height
* as the number of block rows present in the last iMCU row.
@@ -174,7 +264,7 @@ per_scan_setup (j_decompress_ptr cinfo)
compptr->MCU_width = compptr->h_samp_factor;
compptr->MCU_height = compptr->v_samp_factor;
compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
compptr->MCU_sample_width = compptr->MCU_width * compptr->DCT_scaled_size;
compptr->MCU_sample_width = compptr->MCU_width * compptr->_DCT_scaled_size;
/* Figure number of non-dummy blocks in last MCU column & row */
tmp = (int) (compptr->width_in_blocks % compptr->MCU_width);
if (tmp == 0) tmp = compptr->MCU_width;
@@ -301,7 +391,7 @@ consume_markers (j_decompress_ptr cinfo)
initial_setup(cinfo);
inputctl->inheaders = FALSE;
/* Note: start_input_pass must be called by jdmaster.c
* before any more input can be consumed. jdapi.c is
* before any more input can be consumed. jdapimin.c is
* responsible for enforcing this sequencing.
*/
} else { /* 2nd or later SOS marker */

View File

@@ -2,6 +2,7 @@
* jdmainct.c
*
* Copyright (C) 1994-1996, Thomas G. Lane.
* Copyright (C) 2010, 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.
*
@@ -16,6 +17,7 @@
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jpegcomp.h"
/*
@@ -161,7 +163,7 @@ alloc_funny_pointers (j_decompress_ptr cinfo)
{
my_main_ptr main = (my_main_ptr) cinfo->main;
int ci, rgroup;
int M = cinfo->min_DCT_scaled_size;
int M = cinfo->_min_DCT_scaled_size;
jpeg_component_info *compptr;
JSAMPARRAY xbuf;
@@ -175,8 +177,8 @@ alloc_funny_pointers (j_decompress_ptr cinfo)
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
cinfo->min_DCT_scaled_size; /* height of a row group of component */
rgroup = (compptr->v_samp_factor * compptr->_DCT_scaled_size) /
cinfo->_min_DCT_scaled_size; /* height of a row group of component */
/* Get space for pointer lists --- M+4 row groups in each list.
* We alloc both pointer lists with one call to save a few cycles.
*/
@@ -202,14 +204,14 @@ make_funny_pointers (j_decompress_ptr cinfo)
{
my_main_ptr main = (my_main_ptr) cinfo->main;
int ci, i, rgroup;
int M = cinfo->min_DCT_scaled_size;
int M = cinfo->_min_DCT_scaled_size;
jpeg_component_info *compptr;
JSAMPARRAY buf, xbuf0, xbuf1;
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
cinfo->min_DCT_scaled_size; /* height of a row group of component */
rgroup = (compptr->v_samp_factor * compptr->_DCT_scaled_size) /
cinfo->_min_DCT_scaled_size; /* height of a row group of component */
xbuf0 = main->xbuffer[0][ci];
xbuf1 = main->xbuffer[1][ci];
/* First copy the workspace pointers as-is */
@@ -242,14 +244,14 @@ set_wraparound_pointers (j_decompress_ptr cinfo)
{
my_main_ptr main = (my_main_ptr) cinfo->main;
int ci, i, rgroup;
int M = cinfo->min_DCT_scaled_size;
int M = cinfo->_min_DCT_scaled_size;
jpeg_component_info *compptr;
JSAMPARRAY xbuf0, xbuf1;
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
cinfo->min_DCT_scaled_size; /* height of a row group of component */
rgroup = (compptr->v_samp_factor * compptr->_DCT_scaled_size) /
cinfo->_min_DCT_scaled_size; /* height of a row group of component */
xbuf0 = main->xbuffer[0][ci];
xbuf1 = main->xbuffer[1][ci];
for (i = 0; i < rgroup; i++) {
@@ -277,8 +279,8 @@ set_bottom_pointers (j_decompress_ptr cinfo)
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
/* Count sample rows in one iMCU row and in one row group */
iMCUheight = compptr->v_samp_factor * compptr->DCT_scaled_size;
rgroup = iMCUheight / cinfo->min_DCT_scaled_size;
iMCUheight = compptr->v_samp_factor * compptr->_DCT_scaled_size;
rgroup = iMCUheight / cinfo->_min_DCT_scaled_size;
/* Count nondummy sample rows remaining for this component */
rows_left = (int) (compptr->downsampled_height % (JDIMENSION) iMCUheight);
if (rows_left == 0) rows_left = iMCUheight;
@@ -357,7 +359,7 @@ process_data_simple_main (j_decompress_ptr cinfo,
}
/* There are always min_DCT_scaled_size row groups in an iMCU row. */
rowgroups_avail = (JDIMENSION) cinfo->min_DCT_scaled_size;
rowgroups_avail = (JDIMENSION) cinfo->_min_DCT_scaled_size;
/* Note: at the bottom of the image, we may pass extra garbage row groups
* to the postprocessor. The postprocessor has to check for bottom
* of image anyway (at row resolution), so no point in us doing it too.
@@ -417,7 +419,7 @@ process_data_context_main (j_decompress_ptr cinfo,
case CTX_PREPARE_FOR_IMCU:
/* Prepare to process first M-1 row groups of this iMCU row */
main->rowgroup_ctr = 0;
main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size - 1);
main->rowgroups_avail = (JDIMENSION) (cinfo->_min_DCT_scaled_size - 1);
/* Check for bottom of image: if so, tweak pointers to "duplicate"
* the last sample row, and adjust rowgroups_avail to ignore padding rows.
*/
@@ -440,8 +442,8 @@ process_data_context_main (j_decompress_ptr cinfo,
main->buffer_full = FALSE;
/* Still need to process last row group of this iMCU row, */
/* which is saved at index M+1 of the other xbuffer */
main->rowgroup_ctr = (JDIMENSION) (cinfo->min_DCT_scaled_size + 1);
main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size + 2);
main->rowgroup_ctr = (JDIMENSION) (cinfo->_min_DCT_scaled_size + 1);
main->rowgroups_avail = (JDIMENSION) (cinfo->_min_DCT_scaled_size + 2);
main->context_state = CTX_POSTPONED_ROW;
}
}
@@ -492,21 +494,21 @@ jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
* ngroups is the number of row groups we need.
*/
if (cinfo->upsample->need_context_rows) {
if (cinfo->min_DCT_scaled_size < 2) /* unsupported, see comments above */
if (cinfo->_min_DCT_scaled_size < 2) /* unsupported, see comments above */
ERREXIT(cinfo, JERR_NOTIMPL);
alloc_funny_pointers(cinfo); /* Alloc space for xbuffer[] lists */
ngroups = cinfo->min_DCT_scaled_size + 2;
ngroups = cinfo->_min_DCT_scaled_size + 2;
} else {
ngroups = cinfo->min_DCT_scaled_size;
ngroups = cinfo->_min_DCT_scaled_size;
}
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
cinfo->min_DCT_scaled_size; /* height of a row group of component */
rgroup = (compptr->v_samp_factor * compptr->_DCT_scaled_size) /
cinfo->_min_DCT_scaled_size; /* height of a row group of component */
main->buffer[ci] = (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE,
compptr->width_in_blocks * compptr->DCT_scaled_size,
compptr->width_in_blocks * compptr->_DCT_scaled_size,
(JDIMENSION) (rgroup * ngroups));
}
}

View File

@@ -1,7 +1,7 @@
/*
* jdmarker.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Copyright (C) 1991-1998, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -85,6 +85,28 @@ typedef enum { /* JPEG marker codes */
} JPEG_MARKER;
/* Private state */
typedef struct {
struct jpeg_marker_reader pub; /* public fields */
/* Application-overridable marker processing methods */
jpeg_marker_parser_method process_COM;
jpeg_marker_parser_method process_APPn[16];
/* Limit on marker data length to save for each marker type */
unsigned int length_limit_COM;
unsigned int length_limit_APPn[16];
/* Status of COM/APPn marker saving */
jpeg_saved_marker_ptr cur_marker; /* NULL if not processing a marker */
unsigned int bytes_read; /* data bytes read so far in marker */
/* Note: cur_marker is not linked into marker_list until it's all read. */
} my_marker_reader;
typedef my_marker_reader * my_marker_ptr;
/*
* Macros for fetching data from the data source module.
*
@@ -104,7 +126,7 @@ typedef enum { /* JPEG marker codes */
( datasrc->next_input_byte = next_input_byte, \
datasrc->bytes_in_buffer = bytes_in_buffer )
/* Reload the local copies --- seldom used except in MAKE_BYTE_AVAIL */
/* Reload the local copies --- used only in MAKE_BYTE_AVAIL */
#define INPUT_RELOAD(cinfo) \
( next_input_byte = datasrc->next_input_byte, \
bytes_in_buffer = datasrc->bytes_in_buffer )
@@ -118,14 +140,14 @@ typedef enum { /* JPEG marker codes */
if (! (*datasrc->fill_input_buffer) (cinfo)) \
{ action; } \
INPUT_RELOAD(cinfo); \
} \
bytes_in_buffer--
}
/* Read a byte into variable V.
* If must suspend, take the specified action (typically "return FALSE").
*/
#define INPUT_BYTE(cinfo,V,action) \
MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \
bytes_in_buffer--; \
V = GETJOCTET(*next_input_byte++); )
/* As above, but read two bytes interpreted as an unsigned 16-bit integer.
@@ -133,8 +155,10 @@ typedef enum { /* JPEG marker codes */
*/
#define INPUT_2BYTES(cinfo,V,action) \
MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \
bytes_in_buffer--; \
V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \
MAKE_BYTE_AVAIL(cinfo,action); \
bytes_in_buffer--; \
V += GETJOCTET(*next_input_byte++); )
@@ -150,11 +174,18 @@ typedef enum { /* JPEG marker codes */
* marker parameters; restart point has not been moved. Same routine
* will be called again after application supplies more input data.
*
* This approach to suspension assumes that all of a marker's parameters can
* fit into a single input bufferload. This should hold for "normal"
* markers. Some COM/APPn markers might have large parameter segments,
* but we use skip_input_data to get past those, and thereby put the problem
* on the source manager's shoulders.
* This approach to suspension assumes that all of a marker's parameters
* can fit into a single input bufferload. This should hold for "normal"
* markers. Some COM/APPn markers might have large parameter segments
* that might not fit. If we are simply dropping such a marker, we use
* skip_input_data to get past it, and thereby put the problem on the
* source manager's shoulders. If we are saving the marker's contents
* into memory, we use a slightly different convention: when forced to
* suspend, the marker processor updates the restart point to the end of
* what it's consumed (ie, the end of the buffer) before returning FALSE.
* On resumption, cinfo->unread_marker still contains the marker code,
* but the data source will point to the next chunk of marker data.
* The marker processor must retain internal state to deal with this.
*
* Note that we don't bother to avoid duplicate trace messages if a
* suspension occurs within marker parameters. Other side effects
@@ -188,7 +219,9 @@ get_soi (j_decompress_ptr cinfo)
cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling??? */
cinfo->saw_JFIF_marker = FALSE;
cinfo->density_unit = 0; /* set default JFIF APP0 values */
cinfo->JFIF_major_version = 1; /* set default JFIF APP0 values */
cinfo->JFIF_minor_version = 1;
cinfo->density_unit = 0;
cinfo->X_density = 1;
cinfo->Y_density = 1;
cinfo->saw_Adobe_marker = FALSE;
@@ -280,11 +313,11 @@ get_sos (j_decompress_ptr cinfo)
INPUT_BYTE(cinfo, n, return FALSE); /* Number of components */
TRACEMS1(cinfo, 1, JTRC_SOS, n);
if (length != (n * 2 + 6) || n < 1 || n > MAX_COMPS_IN_SCAN)
ERREXIT(cinfo, JERR_BAD_LENGTH);
TRACEMS1(cinfo, 1, JTRC_SOS, n);
cinfo->comps_in_scan = n;
/* Collect the component-spec parameters */
@@ -334,111 +367,7 @@ get_sos (j_decompress_ptr cinfo)
}
METHODDEF(boolean)
get_app0 (j_decompress_ptr cinfo)
/* Process an APP0 marker */
{
#define JFIF_LEN 14
INT32 length;
UINT8 b[JFIF_LEN];
int buffp;
INPUT_VARS(cinfo);
INPUT_2BYTES(cinfo, length, return FALSE);
length -= 2;
/* See if a JFIF APP0 marker is present */
if (length >= JFIF_LEN) {
for (buffp = 0; buffp < JFIF_LEN; buffp++)
INPUT_BYTE(cinfo, b[buffp], return FALSE);
length -= JFIF_LEN;
if (b[0]==0x4A && b[1]==0x46 && b[2]==0x49 && b[3]==0x46 && b[4]==0) {
/* Found JFIF APP0 marker: check version */
/* Major version must be 1, anything else signals an incompatible change.
* We used to treat this as an error, but now it's a nonfatal warning,
* because some bozo at Hijaak couldn't read the spec.
* Minor version should be 0..2, but process anyway if newer.
*/
if (b[5] != 1)
WARNMS2(cinfo, JWRN_JFIF_MAJOR, b[5], b[6]);
else if (b[6] > 2)
TRACEMS2(cinfo, 1, JTRC_JFIF_MINOR, b[5], b[6]);
/* Save info */
cinfo->saw_JFIF_marker = TRUE;
cinfo->density_unit = b[7];
cinfo->X_density = (b[8] << 8) + b[9];
cinfo->Y_density = (b[10] << 8) + b[11];
TRACEMS3(cinfo, 1, JTRC_JFIF,
cinfo->X_density, cinfo->Y_density, cinfo->density_unit);
if (b[12] | b[13])
TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL, b[12], b[13]);
if (length != ((INT32) b[12] * (INT32) b[13] * (INT32) 3))
TRACEMS1(cinfo, 1, JTRC_JFIF_BADTHUMBNAILSIZE, (int) length);
} else {
/* Start of APP0 does not match "JFIF" */
TRACEMS1(cinfo, 1, JTRC_APP0, (int) length + JFIF_LEN);
}
} else {
/* Too short to be JFIF marker */
TRACEMS1(cinfo, 1, JTRC_APP0, (int) length);
}
INPUT_SYNC(cinfo);
if (length > 0) /* skip any remaining data -- could be lots */
(*cinfo->src->skip_input_data) (cinfo, (long) length);
return TRUE;
}
METHODDEF(boolean)
get_app14 (j_decompress_ptr cinfo)
/* Process an APP14 marker */
{
#define ADOBE_LEN 12
INT32 length;
UINT8 b[ADOBE_LEN];
int buffp;
unsigned int version, flags0, flags1, transform;
INPUT_VARS(cinfo);
INPUT_2BYTES(cinfo, length, return FALSE);
length -= 2;
/* See if an Adobe APP14 marker is present */
if (length >= ADOBE_LEN) {
for (buffp = 0; buffp < ADOBE_LEN; buffp++)
INPUT_BYTE(cinfo, b[buffp], return FALSE);
length -= ADOBE_LEN;
if (b[0]==0x41 && b[1]==0x64 && b[2]==0x6F && b[3]==0x62 && b[4]==0x65) {
/* Found Adobe APP14 marker */
version = (b[5] << 8) + b[6];
flags0 = (b[7] << 8) + b[8];
flags1 = (b[9] << 8) + b[10];
transform = b[11];
TRACEMS4(cinfo, 1, JTRC_ADOBE, version, flags0, flags1, transform);
cinfo->saw_Adobe_marker = TRUE;
cinfo->Adobe_transform = (UINT8) transform;
} else {
/* Start of APP14 does not match "Adobe" */
TRACEMS1(cinfo, 1, JTRC_APP14, (int) length + ADOBE_LEN);
}
} else {
/* Too short to be Adobe marker */
TRACEMS1(cinfo, 1, JTRC_APP14, (int) length);
}
INPUT_SYNC(cinfo);
if (length > 0) /* skip any remaining data -- could be lots */
(*cinfo->src->skip_input_data) (cinfo, (long) length);
return TRUE;
}
#ifdef D_ARITH_CODING_SUPPORTED
LOCAL(boolean)
get_dac (j_decompress_ptr cinfo)
@@ -472,10 +401,19 @@ get_dac (j_decompress_ptr cinfo)
}
}
if (length != 0)
ERREXIT(cinfo, JERR_BAD_LENGTH);
INPUT_SYNC(cinfo);
return TRUE;
}
#else /* ! D_ARITH_CODING_SUPPORTED */
#define get_dac(cinfo) skip_variable(cinfo)
#endif /* D_ARITH_CODING_SUPPORTED */
LOCAL(boolean)
get_dht (j_decompress_ptr cinfo)
@@ -491,7 +429,7 @@ get_dht (j_decompress_ptr cinfo)
INPUT_2BYTES(cinfo, length, return FALSE);
length -= 2;
while (length > 0) {
while (length > 16) {
INPUT_BYTE(cinfo, index, return FALSE);
TRACEMS1(cinfo, 1, JTRC_DHT, index);
@@ -512,8 +450,11 @@ get_dht (j_decompress_ptr cinfo)
bits[9], bits[10], bits[11], bits[12],
bits[13], bits[14], bits[15], bits[16]);
/* Here we just do minimal validation of the counts to avoid walking
* off the end of our table space. jdhuff.c will check more carefully.
*/
if (count > 256 || ((INT32) count) > length)
ERREXIT(cinfo, JERR_DHT_COUNTS);
ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
for (i = 0; i < count; i++)
INPUT_BYTE(cinfo, huffval[i], return FALSE);
@@ -537,6 +478,9 @@ get_dht (j_decompress_ptr cinfo)
MEMCOPY((*htblptr)->huffval, huffval, SIZEOF((*htblptr)->huffval));
}
if (length != 0)
ERREXIT(cinfo, JERR_BAD_LENGTH);
INPUT_SYNC(cinfo);
return TRUE;
}
@@ -592,6 +536,9 @@ get_dqt (j_decompress_ptr cinfo)
if (prec) length -= DCTSIZE2;
}
if (length != 0)
ERREXIT(cinfo, JERR_BAD_LENGTH);
INPUT_SYNC(cinfo);
return TRUE;
}
@@ -621,6 +568,279 @@ get_dri (j_decompress_ptr cinfo)
}
/*
* Routines for processing APPn and COM markers.
* These are either saved in memory or discarded, per application request.
* APP0 and APP14 are specially checked to see if they are
* JFIF and Adobe markers, respectively.
*/
#define APP0_DATA_LEN 14 /* Length of interesting data in APP0 */
#define APP14_DATA_LEN 12 /* Length of interesting data in APP14 */
#define APPN_DATA_LEN 14 /* Must be the largest of the above!! */
LOCAL(void)
examine_app0 (j_decompress_ptr cinfo, JOCTET FAR * data,
unsigned int datalen, INT32 remaining)
/* Examine first few bytes from an APP0.
* Take appropriate action if it is a JFIF marker.
* datalen is # of bytes at data[], remaining is length of rest of marker data.
*/
{
INT32 totallen = (INT32) datalen + remaining;
if (datalen >= APP0_DATA_LEN &&
GETJOCTET(data[0]) == 0x4A &&
GETJOCTET(data[1]) == 0x46 &&
GETJOCTET(data[2]) == 0x49 &&
GETJOCTET(data[3]) == 0x46 &&
GETJOCTET(data[4]) == 0) {
/* Found JFIF APP0 marker: save info */
cinfo->saw_JFIF_marker = TRUE;
cinfo->JFIF_major_version = GETJOCTET(data[5]);
cinfo->JFIF_minor_version = GETJOCTET(data[6]);
cinfo->density_unit = GETJOCTET(data[7]);
cinfo->X_density = (GETJOCTET(data[8]) << 8) + GETJOCTET(data[9]);
cinfo->Y_density = (GETJOCTET(data[10]) << 8) + GETJOCTET(data[11]);
/* Check version.
* Major version must be 1, anything else signals an incompatible change.
* (We used to treat this as an error, but now it's a nonfatal warning,
* because some bozo at Hijaak couldn't read the spec.)
* Minor version should be 0..2, but process anyway if newer.
*/
if (cinfo->JFIF_major_version != 1)
WARNMS2(cinfo, JWRN_JFIF_MAJOR,
cinfo->JFIF_major_version, cinfo->JFIF_minor_version);
/* Generate trace messages */
TRACEMS5(cinfo, 1, JTRC_JFIF,
cinfo->JFIF_major_version, cinfo->JFIF_minor_version,
cinfo->X_density, cinfo->Y_density, cinfo->density_unit);
/* Validate thumbnail dimensions and issue appropriate messages */
if (GETJOCTET(data[12]) | GETJOCTET(data[13]))
TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL,
GETJOCTET(data[12]), GETJOCTET(data[13]));
totallen -= APP0_DATA_LEN;
if (totallen !=
((INT32)GETJOCTET(data[12]) * (INT32)GETJOCTET(data[13]) * (INT32) 3))
TRACEMS1(cinfo, 1, JTRC_JFIF_BADTHUMBNAILSIZE, (int) totallen);
} else if (datalen >= 6 &&
GETJOCTET(data[0]) == 0x4A &&
GETJOCTET(data[1]) == 0x46 &&
GETJOCTET(data[2]) == 0x58 &&
GETJOCTET(data[3]) == 0x58 &&
GETJOCTET(data[4]) == 0) {
/* Found JFIF "JFXX" extension APP0 marker */
/* The library doesn't actually do anything with these,
* but we try to produce a helpful trace message.
*/
switch (GETJOCTET(data[5])) {
case 0x10:
TRACEMS1(cinfo, 1, JTRC_THUMB_JPEG, (int) totallen);
break;
case 0x11:
TRACEMS1(cinfo, 1, JTRC_THUMB_PALETTE, (int) totallen);
break;
case 0x13:
TRACEMS1(cinfo, 1, JTRC_THUMB_RGB, (int) totallen);
break;
default:
TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION,
GETJOCTET(data[5]), (int) totallen);
break;
}
} else {
/* Start of APP0 does not match "JFIF" or "JFXX", or too short */
TRACEMS1(cinfo, 1, JTRC_APP0, (int) totallen);
}
}
LOCAL(void)
examine_app14 (j_decompress_ptr cinfo, JOCTET FAR * data,
unsigned int datalen, INT32 remaining)
/* Examine first few bytes from an APP14.
* Take appropriate action if it is an Adobe marker.
* datalen is # of bytes at data[], remaining is length of rest of marker data.
*/
{
unsigned int version, flags0, flags1, transform;
if (datalen >= APP14_DATA_LEN &&
GETJOCTET(data[0]) == 0x41 &&
GETJOCTET(data[1]) == 0x64 &&
GETJOCTET(data[2]) == 0x6F &&
GETJOCTET(data[3]) == 0x62 &&
GETJOCTET(data[4]) == 0x65) {
/* Found Adobe APP14 marker */
version = (GETJOCTET(data[5]) << 8) + GETJOCTET(data[6]);
flags0 = (GETJOCTET(data[7]) << 8) + GETJOCTET(data[8]);
flags1 = (GETJOCTET(data[9]) << 8) + GETJOCTET(data[10]);
transform = GETJOCTET(data[11]);
TRACEMS4(cinfo, 1, JTRC_ADOBE, version, flags0, flags1, transform);
cinfo->saw_Adobe_marker = TRUE;
cinfo->Adobe_transform = (UINT8) transform;
} else {
/* Start of APP14 does not match "Adobe", or too short */
TRACEMS1(cinfo, 1, JTRC_APP14, (int) (datalen + remaining));
}
}
METHODDEF(boolean)
get_interesting_appn (j_decompress_ptr cinfo)
/* Process an APP0 or APP14 marker without saving it */
{
INT32 length;
JOCTET b[APPN_DATA_LEN];
unsigned int i, numtoread;
INPUT_VARS(cinfo);
INPUT_2BYTES(cinfo, length, return FALSE);
length -= 2;
/* get the interesting part of the marker data */
if (length >= APPN_DATA_LEN)
numtoread = APPN_DATA_LEN;
else if (length > 0)
numtoread = (unsigned int) length;
else
numtoread = 0;
for (i = 0; i < numtoread; i++)
INPUT_BYTE(cinfo, b[i], return FALSE);
length -= numtoread;
/* process it */
switch (cinfo->unread_marker) {
case M_APP0:
examine_app0(cinfo, (JOCTET FAR *) b, numtoread, length);
break;
case M_APP14:
examine_app14(cinfo, (JOCTET FAR *) b, numtoread, length);
break;
default:
/* can't get here unless jpeg_save_markers chooses wrong processor */
ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
break;
}
/* skip any remaining data -- could be lots */
INPUT_SYNC(cinfo);
if (length > 0)
(*cinfo->src->skip_input_data) (cinfo, (long) length);
return TRUE;
}
#ifdef SAVE_MARKERS_SUPPORTED
METHODDEF(boolean)
save_marker (j_decompress_ptr cinfo)
/* Save an APPn or COM marker into the marker list */
{
my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
jpeg_saved_marker_ptr cur_marker = marker->cur_marker;
unsigned int bytes_read, data_length;
JOCTET FAR * data;
INT32 length = 0;
INPUT_VARS(cinfo);
if (cur_marker == NULL) {
/* begin reading a marker */
INPUT_2BYTES(cinfo, length, return FALSE);
length -= 2;
if (length >= 0) { /* watch out for bogus length word */
/* figure out how much we want to save */
unsigned int limit;
if (cinfo->unread_marker == (int) M_COM)
limit = marker->length_limit_COM;
else
limit = marker->length_limit_APPn[cinfo->unread_marker - (int) M_APP0];
if ((unsigned int) length < limit)
limit = (unsigned int) length;
/* allocate and initialize the marker item */
cur_marker = (jpeg_saved_marker_ptr)
(*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(struct jpeg_marker_struct) + limit);
cur_marker->next = NULL;
cur_marker->marker = (UINT8) cinfo->unread_marker;
cur_marker->original_length = (unsigned int) length;
cur_marker->data_length = limit;
/* data area is just beyond the jpeg_marker_struct */
data = cur_marker->data = (JOCTET FAR *) (cur_marker + 1);
marker->cur_marker = cur_marker;
marker->bytes_read = 0;
bytes_read = 0;
data_length = limit;
} else {
/* deal with bogus length word */
bytes_read = data_length = 0;
data = NULL;
}
} else {
/* resume reading a marker */
bytes_read = marker->bytes_read;
data_length = cur_marker->data_length;
data = cur_marker->data + bytes_read;
}
while (bytes_read < data_length) {
INPUT_SYNC(cinfo); /* move the restart point to here */
marker->bytes_read = bytes_read;
/* If there's not at least one byte in buffer, suspend */
MAKE_BYTE_AVAIL(cinfo, return FALSE);
/* Copy bytes with reasonable rapidity */
while (bytes_read < data_length && bytes_in_buffer > 0) {
*data++ = *next_input_byte++;
bytes_in_buffer--;
bytes_read++;
}
}
/* Done reading what we want to read */
if (cur_marker != NULL) { /* will be NULL if bogus length word */
/* Add new marker to end of list */
if (cinfo->marker_list == NULL) {
cinfo->marker_list = cur_marker;
} else {
jpeg_saved_marker_ptr prev = cinfo->marker_list;
while (prev->next != NULL)
prev = prev->next;
prev->next = cur_marker;
}
/* Reset pointer & calc remaining data length */
data = cur_marker->data;
length = cur_marker->original_length - data_length;
}
/* Reset to initial state for next marker */
marker->cur_marker = NULL;
/* Process the marker if interesting; else just make a generic trace msg */
switch (cinfo->unread_marker) {
case M_APP0:
examine_app0(cinfo, data, data_length, length);
break;
case M_APP14:
examine_app14(cinfo, data, data_length, length);
break;
default:
TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker,
(int) (data_length + length));
break;
}
/* skip any remaining data -- could be lots */
INPUT_SYNC(cinfo); /* do before skip_input_data */
if (length > 0)
(*cinfo->src->skip_input_data) (cinfo, (long) length);
return TRUE;
}
#endif /* SAVE_MARKERS_SUPPORTED */
METHODDEF(boolean)
skip_variable (j_decompress_ptr cinfo)
/* Skip over an unknown or uninteresting variable-length marker */
@@ -629,11 +849,13 @@ skip_variable (j_decompress_ptr cinfo)
INPUT_VARS(cinfo);
INPUT_2BYTES(cinfo, length, return FALSE);
length -= 2;
TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, (int) length);
INPUT_SYNC(cinfo); /* do before skip_input_data */
(*cinfo->src->skip_input_data) (cinfo, (long) length - 2L);
if (length > 0)
(*cinfo->src->skip_input_data) (cinfo, (long) length);
return TRUE;
}
@@ -833,12 +1055,13 @@ read_markers (j_decompress_ptr cinfo)
case M_APP13:
case M_APP14:
case M_APP15:
if (! (*cinfo->marker->process_APPn[cinfo->unread_marker - (int) M_APP0]) (cinfo))
if (! (*((my_marker_ptr) cinfo->marker)->process_APPn[
cinfo->unread_marker - (int) M_APP0]) (cinfo))
return JPEG_SUSPENDED;
break;
case M_COM:
if (! (*cinfo->marker->process_COM) (cinfo))
if (! (*((my_marker_ptr) cinfo->marker)->process_COM) (cinfo))
return JPEG_SUSPENDED;
break;
@@ -1018,12 +1241,15 @@ jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired)
METHODDEF(void)
reset_marker_reader (j_decompress_ptr cinfo)
{
my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
cinfo->comp_info = NULL; /* until allocated by get_sof */
cinfo->input_scan_number = 0; /* no SOS seen yet */
cinfo->unread_marker = 0; /* no pending marker */
cinfo->marker->saw_SOI = FALSE; /* set internal state too */
cinfo->marker->saw_SOF = FALSE;
cinfo->marker->discarded_bytes = 0;
marker->pub.saw_SOI = FALSE; /* set internal state too */
marker->pub.saw_SOF = FALSE;
marker->pub.discarded_bytes = 0;
marker->cur_marker = NULL;
}
@@ -1035,21 +1261,100 @@ reset_marker_reader (j_decompress_ptr cinfo)
GLOBAL(void)
jinit_marker_reader (j_decompress_ptr cinfo)
{
my_marker_ptr marker;
int i;
/* Create subobject in permanent pool */
cinfo->marker = (struct jpeg_marker_reader *)
marker = (my_marker_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
SIZEOF(struct jpeg_marker_reader));
/* Initialize method pointers */
cinfo->marker->reset_marker_reader = reset_marker_reader;
cinfo->marker->read_markers = read_markers;
cinfo->marker->read_restart_marker = read_restart_marker;
cinfo->marker->process_COM = skip_variable;
for (i = 0; i < 16; i++)
cinfo->marker->process_APPn[i] = skip_variable;
cinfo->marker->process_APPn[0] = get_app0;
cinfo->marker->process_APPn[14] = get_app14;
SIZEOF(my_marker_reader));
cinfo->marker = (struct jpeg_marker_reader *) marker;
/* Initialize public method pointers */
marker->pub.reset_marker_reader = reset_marker_reader;
marker->pub.read_markers = read_markers;
marker->pub.read_restart_marker = read_restart_marker;
/* Initialize COM/APPn processing.
* By default, we examine and then discard APP0 and APP14,
* but simply discard COM and all other APPn.
*/
marker->process_COM = skip_variable;
marker->length_limit_COM = 0;
for (i = 0; i < 16; i++) {
marker->process_APPn[i] = skip_variable;
marker->length_limit_APPn[i] = 0;
}
marker->process_APPn[0] = get_interesting_appn;
marker->process_APPn[14] = get_interesting_appn;
/* Reset marker processing state */
reset_marker_reader(cinfo);
}
/*
* Control saving of COM and APPn markers into marker_list.
*/
#ifdef SAVE_MARKERS_SUPPORTED
GLOBAL(void)
jpeg_save_markers (j_decompress_ptr cinfo, int marker_code,
unsigned int length_limit)
{
my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
long maxlength;
jpeg_marker_parser_method processor;
/* Length limit mustn't be larger than what we can allocate
* (should only be a concern in a 16-bit environment).
*/
maxlength = cinfo->mem->max_alloc_chunk - SIZEOF(struct jpeg_marker_struct);
if (((long) length_limit) > maxlength)
length_limit = (unsigned int) maxlength;
/* Choose processor routine to use.
* APP0/APP14 have special requirements.
*/
if (length_limit) {
processor = save_marker;
/* If saving APP0/APP14, save at least enough for our internal use. */
if (marker_code == (int) M_APP0 && length_limit < APP0_DATA_LEN)
length_limit = APP0_DATA_LEN;
else if (marker_code == (int) M_APP14 && length_limit < APP14_DATA_LEN)
length_limit = APP14_DATA_LEN;
} else {
processor = skip_variable;
/* If discarding APP0/APP14, use our regular on-the-fly processor. */
if (marker_code == (int) M_APP0 || marker_code == (int) M_APP14)
processor = get_interesting_appn;
}
if (marker_code == (int) M_COM) {
marker->process_COM = processor;
marker->length_limit_COM = length_limit;
} else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15) {
marker->process_APPn[marker_code - (int) M_APP0] = processor;
marker->length_limit_APPn[marker_code - (int) M_APP0] = length_limit;
} else
ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);
}
#endif /* SAVE_MARKERS_SUPPORTED */
/*
* Install a special processing method for COM or APPn markers.
*/
GLOBAL(void)
jpeg_set_marker_processor (j_decompress_ptr cinfo, int marker_code,
jpeg_marker_parser_method routine)
{
my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
if (marker_code == (int) M_COM)
marker->process_COM = routine;
else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15)
marker->process_APPn[marker_code - (int) M_APP0] = routine;
else
ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);
}

View File

@@ -1,7 +1,8 @@
/*
* jdmaster.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Copyright (C) 1991-1997, Thomas G. Lane.
* Copyright (C) 2009-2010, 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.
*
@@ -14,6 +15,7 @@
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jpegcomp.h"
/* Private state */
@@ -49,8 +51,14 @@ use_merged_upsample (j_decompress_ptr cinfo)
return FALSE;
/* jdmerge.c only supports YCC=>RGB color conversion */
if (cinfo->jpeg_color_space != JCS_YCbCr || cinfo->num_components != 3 ||
cinfo->out_color_space != JCS_RGB ||
cinfo->out_color_components != RGB_PIXELSIZE)
(cinfo->out_color_space != JCS_RGB &&
cinfo->out_color_space != JCS_EXT_RGB &&
cinfo->out_color_space != JCS_EXT_RGBX &&
cinfo->out_color_space != JCS_EXT_BGR &&
cinfo->out_color_space != JCS_EXT_BGRX &&
cinfo->out_color_space != JCS_EXT_XBGR &&
cinfo->out_color_space != JCS_EXT_XRGB) ||
cinfo->out_color_components != rgb_pixelsize[cinfo->out_color_space])
return FALSE;
/* and it only handles 2h1v or 2h2v sampling ratios */
if (cinfo->comp_info[0].h_samp_factor != 2 ||
@@ -61,9 +69,9 @@ use_merged_upsample (j_decompress_ptr cinfo)
cinfo->comp_info[2].v_samp_factor != 1)
return FALSE;
/* furthermore, it doesn't work if we've scaled the IDCTs differently */
if (cinfo->comp_info[0].DCT_scaled_size != cinfo->min_DCT_scaled_size ||
cinfo->comp_info[1].DCT_scaled_size != cinfo->min_DCT_scaled_size ||
cinfo->comp_info[2].DCT_scaled_size != cinfo->min_DCT_scaled_size)
if (cinfo->comp_info[0]._DCT_scaled_size != cinfo->_min_DCT_scaled_size ||
cinfo->comp_info[1]._DCT_scaled_size != cinfo->_min_DCT_scaled_size ||
cinfo->comp_info[2]._DCT_scaled_size != cinfo->_min_DCT_scaled_size)
return FALSE;
/* ??? also need to test for upsample-time rescaling, when & if supported */
return TRUE; /* by golly, it'll work... */
@@ -84,8 +92,10 @@ GLOBAL(void)
jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
/* Do computations that are needed before master selection phase */
{
#ifdef IDCT_SCALING_SUPPORTED
int ci;
jpeg_component_info *compptr;
#endif
/* Prevent application from calling me at wrong times */
if (cinfo->global_state != DSTATE_READY)
@@ -100,26 +110,42 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
jdiv_round_up((long) cinfo->image_width, 8L);
cinfo->output_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height, 8L);
#if JPEG_LIB_VERSION >= 70
cinfo->min_DCT_h_scaled_size = cinfo->min_DCT_v_scaled_size = 1;
#else
cinfo->min_DCT_scaled_size = 1;
#endif
} else if (cinfo->scale_num * 4 <= cinfo->scale_denom) {
/* Provide 1/4 scaling */
cinfo->output_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width, 4L);
cinfo->output_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height, 4L);
#if JPEG_LIB_VERSION >= 70
cinfo->min_DCT_h_scaled_size = cinfo->min_DCT_v_scaled_size = 2;
#else
cinfo->min_DCT_scaled_size = 2;
#endif
} else if (cinfo->scale_num * 2 <= cinfo->scale_denom) {
/* Provide 1/2 scaling */
cinfo->output_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width, 2L);
cinfo->output_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height, 2L);
#if JPEG_LIB_VERSION >= 70
cinfo->min_DCT_h_scaled_size = cinfo->min_DCT_v_scaled_size = 4;
#else
cinfo->min_DCT_scaled_size = 4;
#endif
} else {
/* Provide 1/1 scaling */
cinfo->output_width = cinfo->image_width;
cinfo->output_height = cinfo->image_height;
#if JPEG_LIB_VERSION >= 70
cinfo->min_DCT_h_scaled_size = cinfo->min_DCT_v_scaled_size = DCTSIZE;
#else
cinfo->min_DCT_scaled_size = DCTSIZE;
#endif
}
/* In selecting the actual DCT scaling for each component, we try to
* scale up the chroma components via IDCT scaling rather than upsampling.
@@ -128,15 +154,19 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
*/
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
int ssize = cinfo->min_DCT_scaled_size;
int ssize = cinfo->_min_DCT_scaled_size;
while (ssize < DCTSIZE &&
(compptr->h_samp_factor * ssize * 2 <=
cinfo->max_h_samp_factor * cinfo->min_DCT_scaled_size) &&
cinfo->max_h_samp_factor * cinfo->_min_DCT_scaled_size) &&
(compptr->v_samp_factor * ssize * 2 <=
cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size)) {
cinfo->max_v_samp_factor * cinfo->_min_DCT_scaled_size)) {
ssize = ssize * 2;
}
#if JPEG_LIB_VERSION >= 70
compptr->DCT_h_scaled_size = compptr->DCT_v_scaled_size = ssize;
#else
compptr->DCT_scaled_size = ssize;
#endif
}
/* Recompute downsampled dimensions of components;
@@ -147,11 +177,11 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
/* Size in samples, after IDCT scaling */
compptr->downsampled_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width *
(long) (compptr->h_samp_factor * compptr->DCT_scaled_size),
(long) (compptr->h_samp_factor * compptr->_DCT_scaled_size),
(long) (cinfo->max_h_samp_factor * DCTSIZE));
compptr->downsampled_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height *
(long) (compptr->v_samp_factor * compptr->DCT_scaled_size),
(long) (compptr->v_samp_factor * compptr->_DCT_scaled_size),
(long) (cinfo->max_v_samp_factor * DCTSIZE));
}
@@ -173,10 +203,14 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
cinfo->out_color_components = 1;
break;
case JCS_RGB:
#if RGB_PIXELSIZE != 3
cinfo->out_color_components = RGB_PIXELSIZE;
case JCS_EXT_RGB:
case JCS_EXT_RGBX:
case JCS_EXT_BGR:
case JCS_EXT_BGRX:
case JCS_EXT_XBGR:
case JCS_EXT_XRGB:
cinfo->out_color_components = rgb_pixelsize[cinfo->out_color_space];
break;
#endif /* else share code with YCbCr */
case JCS_YCbCr:
cinfo->out_color_components = 3;
break;
@@ -371,7 +405,11 @@ master_selection (j_decompress_ptr cinfo)
jinit_inverse_dct(cinfo);
/* Entropy decoding: either Huffman or arithmetic coding. */
if (cinfo->arith_code) {
#ifdef D_ARITH_CODING_SUPPORTED
jinit_arith_decoder(cinfo);
#else
ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
#endif
} else {
if (cinfo->progressive_mode) {
#ifdef D_PROGRESSIVE_SUPPORTED
@@ -429,7 +467,7 @@ master_selection (j_decompress_ptr cinfo)
* modules will be active during this pass and give them appropriate
* start_pass calls. We also set is_dummy_pass to indicate whether this
* is a "real" output pass or a dummy pass for color quantization.
* (In the latter case, jdapi.c will crank the pass to completion.)
* (In the latter case, jdapistd.c will crank the pass to completion.)
*/
METHODDEF(void)

View File

@@ -2,6 +2,8 @@
* jdmerge.c
*
* Copyright (C) 1994-1996, Thomas G. Lane.
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
* Copyright (C) 2009, 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.
*
@@ -35,6 +37,7 @@
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jsimd.h"
#ifdef UPSAMPLE_MERGING_SUPPORTED
@@ -255,15 +258,15 @@ h2v1_merged_upsample (j_decompress_ptr cinfo,
cblue = Cbbtab[cb];
/* Fetch 2 Y values and emit 2 pixels */
y = GETJSAMPLE(*inptr0++);
outptr[RGB_RED] = range_limit[y + cred];
outptr[RGB_GREEN] = range_limit[y + cgreen];
outptr[RGB_BLUE] = range_limit[y + cblue];
outptr += RGB_PIXELSIZE;
outptr[rgb_red[cinfo->out_color_space]] = range_limit[y + cred];
outptr[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
outptr[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
outptr += rgb_pixelsize[cinfo->out_color_space];
y = GETJSAMPLE(*inptr0++);
outptr[RGB_RED] = range_limit[y + cred];
outptr[RGB_GREEN] = range_limit[y + cgreen];
outptr[RGB_BLUE] = range_limit[y + cblue];
outptr += RGB_PIXELSIZE;
outptr[rgb_red[cinfo->out_color_space]] = range_limit[y + cred];
outptr[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
outptr[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
outptr += rgb_pixelsize[cinfo->out_color_space];
}
/* If image width is odd, do the last output column separately */
if (cinfo->output_width & 1) {
@@ -273,9 +276,9 @@ h2v1_merged_upsample (j_decompress_ptr cinfo,
cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
cblue = Cbbtab[cb];
y = GETJSAMPLE(*inptr0);
outptr[RGB_RED] = range_limit[y + cred];
outptr[RGB_GREEN] = range_limit[y + cgreen];
outptr[RGB_BLUE] = range_limit[y + cblue];
outptr[rgb_red[cinfo->out_color_space]] = range_limit[y + cred];
outptr[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
outptr[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
}
}
@@ -319,24 +322,24 @@ h2v2_merged_upsample (j_decompress_ptr cinfo,
cblue = Cbbtab[cb];
/* Fetch 4 Y values and emit 4 pixels */
y = GETJSAMPLE(*inptr00++);
outptr0[RGB_RED] = range_limit[y + cred];
outptr0[RGB_GREEN] = range_limit[y + cgreen];
outptr0[RGB_BLUE] = range_limit[y + cblue];
outptr0[rgb_red[cinfo->out_color_space]] = range_limit[y + cred];
outptr0[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
outptr0[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
outptr0 += RGB_PIXELSIZE;
y = GETJSAMPLE(*inptr00++);
outptr0[RGB_RED] = range_limit[y + cred];
outptr0[RGB_GREEN] = range_limit[y + cgreen];
outptr0[RGB_BLUE] = range_limit[y + cblue];
outptr0[rgb_red[cinfo->out_color_space]] = range_limit[y + cred];
outptr0[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
outptr0[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
outptr0 += RGB_PIXELSIZE;
y = GETJSAMPLE(*inptr01++);
outptr1[RGB_RED] = range_limit[y + cred];
outptr1[RGB_GREEN] = range_limit[y + cgreen];
outptr1[RGB_BLUE] = range_limit[y + cblue];
outptr1[rgb_red[cinfo->out_color_space]] = range_limit[y + cred];
outptr1[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
outptr1[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
outptr1 += RGB_PIXELSIZE;
y = GETJSAMPLE(*inptr01++);
outptr1[RGB_RED] = range_limit[y + cred];
outptr1[RGB_GREEN] = range_limit[y + cgreen];
outptr1[RGB_BLUE] = range_limit[y + cblue];
outptr1[rgb_red[cinfo->out_color_space]] = range_limit[y + cred];
outptr1[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
outptr1[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
outptr1 += RGB_PIXELSIZE;
}
/* If image width is odd, do the last output column separately */
@@ -347,13 +350,13 @@ h2v2_merged_upsample (j_decompress_ptr cinfo,
cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
cblue = Cbbtab[cb];
y = GETJSAMPLE(*inptr00);
outptr0[RGB_RED] = range_limit[y + cred];
outptr0[RGB_GREEN] = range_limit[y + cgreen];
outptr0[RGB_BLUE] = range_limit[y + cblue];
outptr0[rgb_red[cinfo->out_color_space]] = range_limit[y + cred];
outptr0[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
outptr0[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
y = GETJSAMPLE(*inptr01);
outptr1[RGB_RED] = range_limit[y + cred];
outptr1[RGB_GREEN] = range_limit[y + cgreen];
outptr1[RGB_BLUE] = range_limit[y + cblue];
outptr1[rgb_red[cinfo->out_color_space]] = range_limit[y + cred];
outptr1[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
outptr1[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
}
}
@@ -382,14 +385,20 @@ jinit_merged_upsampler (j_decompress_ptr cinfo)
if (cinfo->max_v_samp_factor == 2) {
upsample->pub.upsample = merged_2v_upsample;
upsample->upmethod = h2v2_merged_upsample;
if (jsimd_can_h2v2_merged_upsample())
upsample->upmethod = jsimd_h2v2_merged_upsample;
else
upsample->upmethod = h2v2_merged_upsample;
/* Allocate a spare row buffer */
upsample->spare_row = (JSAMPROW)
(*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(size_t) (upsample->out_row_width * SIZEOF(JSAMPLE)));
} else {
upsample->pub.upsample = merged_1v_upsample;
upsample->upmethod = h2v1_merged_upsample;
if (jsimd_can_h2v1_merged_upsample())
upsample->upmethod = jsimd_h2v1_merged_upsample;
else
upsample->upmethod = h2v1_merged_upsample;
/* No spare row needed */
upsample->spare_row = NULL;
}

334
jdphuff.c
View File

@@ -1,7 +1,7 @@
/*
* jdphuff.c
*
* Copyright (C) 1995-1996, Thomas G. Lane.
* Copyright (C) 1995-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -119,6 +119,12 @@ start_pass_phuff_decoder (j_decompress_ptr cinfo)
}
if (cinfo->Al > 13) /* need not check for < 0 */
bad = TRUE;
/* Arguably the maximum Al value should be less than 13 for 8-bit precision,
* but the spec doesn't say so, and we try to be liberal about what we
* accept. Note: large Al values could result in out-of-range DC
* coefficients during early scans, leading to bizarre displays due to
* overflows in the IDCT math. But we won't crash.
*/
if (bad)
ERREXIT4(cinfo, JERR_BAD_PROGRESSION,
cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al);
@@ -160,18 +166,12 @@ start_pass_phuff_decoder (j_decompress_ptr cinfo)
if (is_DC_band) {
if (cinfo->Ah == 0) { /* DC refinement needs no table */
tbl = compptr->dc_tbl_no;
if (tbl < 0 || tbl >= NUM_HUFF_TBLS ||
cinfo->dc_huff_tbl_ptrs[tbl] == NULL)
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tbl);
jpeg_make_d_derived_tbl(cinfo, cinfo->dc_huff_tbl_ptrs[tbl],
jpeg_make_d_derived_tbl(cinfo, TRUE, tbl,
& entropy->derived_tbls[tbl]);
}
} else {
tbl = compptr->ac_tbl_no;
if (tbl < 0 || tbl >= NUM_HUFF_TBLS ||
cinfo->ac_huff_tbl_ptrs[tbl] == NULL)
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tbl);
jpeg_make_d_derived_tbl(cinfo, cinfo->ac_huff_tbl_ptrs[tbl],
jpeg_make_d_derived_tbl(cinfo, FALSE, tbl,
& entropy->derived_tbls[tbl]);
/* remember the single active table */
entropy->ac_derived_tbl = entropy->derived_tbls[tbl];
@@ -183,7 +183,7 @@ start_pass_phuff_decoder (j_decompress_ptr cinfo)
/* Initialize bitread state variables */
entropy->bitstate.bits_left = 0;
entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */
entropy->bitstate.printed_eod = FALSE;
entropy->pub.insufficient_data = FALSE;
/* Initialize private state variables */
entropy->saved.EOBRUN = 0;
@@ -248,8 +248,13 @@ process_restart (j_decompress_ptr cinfo)
/* Reset restart counter */
entropy->restarts_to_go = cinfo->restart_interval;
/* Next segment can get another out-of-data warning */
entropy->bitstate.printed_eod = FALSE;
/* Reset out-of-data flag, unless read_restart_marker left us smack up
* against a marker. In that case we will end up treating the next data
* segment as empty, and we can avoid producing bogus output pixels by
* leaving the flag set.
*/
if (cinfo->unread_marker == 0)
entropy->pub.insufficient_data = FALSE;
return TRUE;
}
@@ -297,39 +302,45 @@ decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
return FALSE;
}
/* Load up working state */
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
ASSIGN_STATE(state, entropy->saved);
/* If we've run out of data, just leave the MCU set to zeroes.
* This way, we return uniform gray for the remainder of the segment.
*/
if (! entropy->pub.insufficient_data) {
/* Outer loop handles each block in the MCU */
/* Load up working state */
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
ASSIGN_STATE(state, entropy->saved);
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
block = MCU_data[blkn];
ci = cinfo->MCU_membership[blkn];
compptr = cinfo->cur_comp_info[ci];
tbl = entropy->derived_tbls[compptr->dc_tbl_no];
/* Outer loop handles each block in the MCU */
/* Decode a single block's worth of coefficients */
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
block = MCU_data[blkn];
ci = cinfo->MCU_membership[blkn];
compptr = cinfo->cur_comp_info[ci];
tbl = entropy->derived_tbls[compptr->dc_tbl_no];
/* Section F.2.2.1: decode the DC coefficient difference */
HUFF_DECODE(s, br_state, tbl, return FALSE, label1);
if (s) {
CHECK_BIT_BUFFER(br_state, s, return FALSE);
r = GET_BITS(s);
s = HUFF_EXTEND(r, s);
/* Decode a single block's worth of coefficients */
/* Section F.2.2.1: decode the DC coefficient difference */
HUFF_DECODE(s, br_state, tbl, return FALSE, label1);
if (s) {
CHECK_BIT_BUFFER(br_state, s, return FALSE);
r = GET_BITS(s);
s = HUFF_EXTEND(r, s);
}
/* Convert DC difference to actual value, update last_dc_val */
s += state.last_dc_val[ci];
state.last_dc_val[ci] = s;
/* Scale and output the coefficient (assumes jpeg_natural_order[0]=0) */
(*block)[0] = (JCOEF) (s << Al);
}
/* Convert DC difference to actual value, update last_dc_val */
s += state.last_dc_val[ci];
state.last_dc_val[ci] = s;
/* Scale and output the DC coefficient (assumes jpeg_natural_order[0]=0) */
(*block)[0] = (JCOEF) (s << Al);
/* Completed MCU, so update state */
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
ASSIGN_STATE(entropy->saved, state);
}
/* Completed MCU, so update state */
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
ASSIGN_STATE(entropy->saved, state);
/* Account for restart interval (no-op if not using restarts) */
entropy->restarts_to_go--;
@@ -361,53 +372,59 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
return FALSE;
}
/* Load up working state.
* We can avoid loading/saving bitread state if in an EOB run.
/* If we've run out of data, just leave the MCU set to zeroes.
* This way, we return uniform gray for the remainder of the segment.
*/
EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we care about */
if (! entropy->pub.insufficient_data) {
/* There is always only one block per MCU */
/* Load up working state.
* We can avoid loading/saving bitread state if in an EOB run.
*/
EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we need */
if (EOBRUN > 0) /* if it's a band of zeroes... */
EOBRUN--; /* ...process it now (we do nothing) */
else {
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
block = MCU_data[0];
tbl = entropy->ac_derived_tbl;
/* There is always only one block per MCU */
for (k = cinfo->Ss; k <= Se; k++) {
HUFF_DECODE(s, br_state, tbl, return FALSE, label2);
r = s >> 4;
s &= 15;
if (s) {
k += r;
CHECK_BIT_BUFFER(br_state, s, return FALSE);
r = GET_BITS(s);
s = HUFF_EXTEND(r, s);
/* Scale and output coefficient in natural (dezigzagged) order */
(*block)[jpeg_natural_order[k]] = (JCOEF) (s << Al);
} else {
if (r == 15) { /* ZRL */
k += 15; /* skip 15 zeroes in band */
} else { /* EOBr, run length is 2^r + appended bits */
EOBRUN = 1 << r;
if (r) { /* EOBr, r > 0 */
CHECK_BIT_BUFFER(br_state, r, return FALSE);
r = GET_BITS(r);
EOBRUN += r;
}
EOBRUN--; /* this band is processed at this moment */
break; /* force end-of-band */
if (EOBRUN > 0) /* if it's a band of zeroes... */
EOBRUN--; /* ...process it now (we do nothing) */
else {
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
block = MCU_data[0];
tbl = entropy->ac_derived_tbl;
for (k = cinfo->Ss; k <= Se; k++) {
HUFF_DECODE(s, br_state, tbl, return FALSE, label2);
r = s >> 4;
s &= 15;
if (s) {
k += r;
CHECK_BIT_BUFFER(br_state, s, return FALSE);
r = GET_BITS(s);
s = HUFF_EXTEND(r, s);
/* Scale and output coefficient in natural (dezigzagged) order */
(*block)[jpeg_natural_order[k]] = (JCOEF) (s << Al);
} else {
if (r == 15) { /* ZRL */
k += 15; /* skip 15 zeroes in band */
} else { /* EOBr, run length is 2^r + appended bits */
EOBRUN = 1 << r;
if (r) { /* EOBr, r > 0 */
CHECK_BIT_BUFFER(br_state, r, return FALSE);
r = GET_BITS(r);
EOBRUN += r;
}
EOBRUN--; /* this band is processed at this moment */
break; /* force end-of-band */
}
}
}
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
}
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
/* Completed MCU, so update state */
entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */
}
/* Completed MCU, so update state */
entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we care about */
/* Account for restart interval (no-op if not using restarts) */
entropy->restarts_to_go--;
@@ -437,6 +454,10 @@ decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
return FALSE;
}
/* Not worth the cycles to check insufficient_data here,
* since we will not change the data anyway if we read zeroes.
*/
/* Load up working state */
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
@@ -489,55 +510,93 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
return FALSE;
}
/* Load up working state */
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we care about */
/* There is always only one block per MCU */
block = MCU_data[0];
tbl = entropy->ac_derived_tbl;
/* If we are forced to suspend, we must undo the assignments to any newly
* nonzero coefficients in the block, because otherwise we'd get confused
* next time about which coefficients were already nonzero.
* But we need not undo addition of bits to already-nonzero coefficients;
* instead, we can test the current bit position to see if we already did it.
/* If we've run out of data, don't modify the MCU.
*/
num_newnz = 0;
if (! entropy->pub.insufficient_data) {
/* initialize coefficient loop counter to start of band */
k = cinfo->Ss;
/* Load up working state */
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we need */
if (EOBRUN == 0) {
for (; k <= Se; k++) {
HUFF_DECODE(s, br_state, tbl, goto undoit, label3);
r = s >> 4;
s &= 15;
if (s) {
if (s != 1) /* size of new coef should always be 1 */
WARNMS(cinfo, JWRN_HUFF_BAD_CODE);
CHECK_BIT_BUFFER(br_state, 1, goto undoit);
if (GET_BITS(1))
s = p1; /* newly nonzero coef is positive */
else
s = m1; /* newly nonzero coef is negative */
} else {
if (r != 15) {
EOBRUN = 1 << r; /* EOBr, run length is 2^r + appended bits */
if (r) {
CHECK_BIT_BUFFER(br_state, r, goto undoit);
r = GET_BITS(r);
EOBRUN += r;
/* There is always only one block per MCU */
block = MCU_data[0];
tbl = entropy->ac_derived_tbl;
/* If we are forced to suspend, we must undo the assignments to any newly
* nonzero coefficients in the block, because otherwise we'd get confused
* next time about which coefficients were already nonzero.
* But we need not undo addition of bits to already-nonzero coefficients;
* instead, we can test the current bit to see if we already did it.
*/
num_newnz = 0;
/* initialize coefficient loop counter to start of band */
k = cinfo->Ss;
if (EOBRUN == 0) {
for (; k <= Se; k++) {
HUFF_DECODE(s, br_state, tbl, goto undoit, label3);
r = s >> 4;
s &= 15;
if (s) {
if (s != 1) /* size of new coef should always be 1 */
WARNMS(cinfo, JWRN_HUFF_BAD_CODE);
CHECK_BIT_BUFFER(br_state, 1, goto undoit);
if (GET_BITS(1))
s = p1; /* newly nonzero coef is positive */
else
s = m1; /* newly nonzero coef is negative */
} else {
if (r != 15) {
EOBRUN = 1 << r; /* EOBr, run length is 2^r + appended bits */
if (r) {
CHECK_BIT_BUFFER(br_state, r, goto undoit);
r = GET_BITS(r);
EOBRUN += r;
}
break; /* rest of block is handled by EOB logic */
}
break; /* rest of block is handled by EOB logic */
/* note s = 0 for processing ZRL */
}
/* Advance over already-nonzero coefs and r still-zero coefs,
* appending correction bits to the nonzeroes. A correction bit is 1
* if the absolute value of the coefficient must be increased.
*/
do {
thiscoef = *block + jpeg_natural_order[k];
if (*thiscoef != 0) {
CHECK_BIT_BUFFER(br_state, 1, goto undoit);
if (GET_BITS(1)) {
if ((*thiscoef & p1) == 0) { /* do nothing if already set it */
if (*thiscoef >= 0)
*thiscoef += p1;
else
*thiscoef += m1;
}
}
} else {
if (--r < 0)
break; /* reached target zero coefficient */
}
k++;
} while (k <= Se);
if (s) {
int pos = jpeg_natural_order[k];
/* Output newly nonzero coefficient */
(*block)[pos] = (JCOEF) s;
/* Remember its position in case we have to suspend */
newnz_pos[num_newnz++] = pos;
}
/* note s = 0 for processing ZRL */
}
/* Advance over already-nonzero coefs and r still-zero coefs,
* appending correction bits to the nonzeroes. A correction bit is 1
}
if (EOBRUN > 0) {
/* Scan any remaining coefficient positions after the end-of-band
* (the last newly nonzero coefficient, if any). Append a correction
* bit to each already-nonzero coefficient. A correction bit is 1
* if the absolute value of the coefficient must be increased.
*/
do {
for (; k <= Se; k++) {
thiscoef = *block + jpeg_natural_order[k];
if (*thiscoef != 0) {
CHECK_BIT_BUFFER(br_state, 1, goto undoit);
@@ -549,49 +608,16 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
*thiscoef += m1;
}
}
} else {
if (--r < 0)
break; /* reached target zero coefficient */
}
k++;
} while (k <= Se);
if (s) {
int pos = jpeg_natural_order[k];
/* Output newly nonzero coefficient */
(*block)[pos] = (JCOEF) s;
/* Remember its position in case we have to suspend */
newnz_pos[num_newnz++] = pos;
}
}
}
if (EOBRUN > 0) {
/* Scan any remaining coefficient positions after the end-of-band
* (the last newly nonzero coefficient, if any). Append a correction
* bit to each already-nonzero coefficient. A correction bit is 1
* if the absolute value of the coefficient must be increased.
*/
for (; k <= Se; k++) {
thiscoef = *block + jpeg_natural_order[k];
if (*thiscoef != 0) {
CHECK_BIT_BUFFER(br_state, 1, goto undoit);
if (GET_BITS(1)) {
if ((*thiscoef & p1) == 0) { /* do nothing if already changed it */
if (*thiscoef >= 0)
*thiscoef += p1;
else
*thiscoef += m1;
}
}
}
/* Count one block completed in EOB run */
EOBRUN--;
}
/* Count one block completed in EOB run */
EOBRUN--;
}
/* Completed MCU, so update state */
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we care about */
/* Completed MCU, so update state */
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */
}
/* Account for restart interval (no-op if not using restarts) */
entropy->restarts_to_go--;

View File

@@ -2,6 +2,8 @@
* jdsample.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
* Copyright (C) 2010, 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.
*
@@ -21,6 +23,8 @@
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jsimd.h"
#include "jpegcomp.h"
/* Pointer to routine to upsample a single component */
@@ -418,7 +422,7 @@ jinit_upsampler (j_decompress_ptr cinfo)
/* jdmainct.c doesn't support context rows when min_DCT_scaled_size = 1,
* so don't ask for it.
*/
do_fancy = cinfo->do_fancy_upsampling && cinfo->min_DCT_scaled_size > 1;
do_fancy = cinfo->do_fancy_upsampling && cinfo->_min_DCT_scaled_size > 1;
/* Verify we can handle the sampling factors, select per-component methods,
* and create storage as needed.
@@ -428,10 +432,10 @@ jinit_upsampler (j_decompress_ptr cinfo)
/* Compute size of an "input group" after IDCT scaling. This many samples
* are to be converted to max_h_samp_factor * max_v_samp_factor pixels.
*/
h_in_group = (compptr->h_samp_factor * compptr->DCT_scaled_size) /
cinfo->min_DCT_scaled_size;
v_in_group = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
cinfo->min_DCT_scaled_size;
h_in_group = (compptr->h_samp_factor * compptr->_DCT_scaled_size) /
cinfo->_min_DCT_scaled_size;
v_in_group = (compptr->v_samp_factor * compptr->_DCT_scaled_size) /
cinfo->_min_DCT_scaled_size;
h_out_group = cinfo->max_h_samp_factor;
v_out_group = cinfo->max_v_samp_factor;
upsample->rowgroup_height[ci] = v_in_group; /* save for use later */
@@ -447,18 +451,32 @@ jinit_upsampler (j_decompress_ptr cinfo)
} else if (h_in_group * 2 == h_out_group &&
v_in_group == v_out_group) {
/* Special cases for 2h1v upsampling */
if (do_fancy && compptr->downsampled_width > 2)
upsample->methods[ci] = h2v1_fancy_upsample;
else
upsample->methods[ci] = h2v1_upsample;
if (do_fancy && compptr->downsampled_width > 2) {
if (jsimd_can_h2v1_fancy_upsample())
upsample->methods[ci] = jsimd_h2v1_fancy_upsample;
else
upsample->methods[ci] = h2v1_fancy_upsample;
} else {
if (jsimd_can_h2v1_upsample())
upsample->methods[ci] = jsimd_h2v1_upsample;
else
upsample->methods[ci] = h2v1_upsample;
}
} else if (h_in_group * 2 == h_out_group &&
v_in_group * 2 == v_out_group) {
/* Special cases for 2h2v upsampling */
if (do_fancy && compptr->downsampled_width > 2) {
upsample->methods[ci] = h2v2_fancy_upsample;
if (jsimd_can_h2v2_fancy_upsample())
upsample->methods[ci] = jsimd_h2v2_fancy_upsample;
else
upsample->methods[ci] = h2v2_fancy_upsample;
upsample->pub.need_context_rows = TRUE;
} else
upsample->methods[ci] = h2v2_upsample;
} else {
if (jsimd_can_h2v2_upsample())
upsample->methods[ci] = jsimd_h2v2_upsample;
else
upsample->methods[ci] = h2v2_upsample;
}
} else if ((h_out_group % h_in_group) == 0 &&
(v_out_group % v_in_group) == 0) {
/* Generic integral-factors upsampling method */

View File

@@ -1,7 +1,7 @@
/*
* jdtrans.c
*
* Copyright (C) 1995-1996, Thomas G. Lane.
* Copyright (C) 1995-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -30,6 +30,13 @@ LOCAL(void) transdecode_master_selection JPP((j_decompress_ptr cinfo));
* To release the memory occupied by the virtual arrays, call
* jpeg_finish_decompress() when done with the data.
*
* An alternative usage is to simply obtain access to the coefficient arrays
* during a buffered-image-mode decompression operation. This is allowed
* after any jpeg_finish_output() call. The arrays can be accessed until
* jpeg_finish_decompress() is called. (Note that any call to the library
* may reposition the arrays, so don't rely on access_virt_barray() results
* to stay valid across library calls.)
*
* Returns NULL if suspended. This case need be checked only if
* a suspending data source is used.
*/
@@ -41,32 +48,43 @@ jpeg_read_coefficients (j_decompress_ptr cinfo)
/* First call: initialize active modules */
transdecode_master_selection(cinfo);
cinfo->global_state = DSTATE_RDCOEFS;
} else if (cinfo->global_state != DSTATE_RDCOEFS)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
/* Absorb whole file into the coef buffer */
for (;;) {
int retcode;
/* Call progress monitor hook if present */
if (cinfo->progress != NULL)
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
/* Absorb some more input */
retcode = (*cinfo->inputctl->consume_input) (cinfo);
if (retcode == JPEG_SUSPENDED)
return NULL;
if (retcode == JPEG_REACHED_EOI)
break;
/* Advance progress counter if appropriate */
if (cinfo->progress != NULL &&
(retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) {
if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) {
/* startup underestimated number of scans; ratchet up one scan */
cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows;
}
if (cinfo->global_state == DSTATE_RDCOEFS) {
/* Absorb whole file into the coef buffer */
for (;;) {
int retcode;
/* Call progress monitor hook if present */
if (cinfo->progress != NULL)
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
/* Absorb some more input */
retcode = (*cinfo->inputctl->consume_input) (cinfo);
if (retcode == JPEG_SUSPENDED)
return NULL;
if (retcode == JPEG_REACHED_EOI)
break;
/* Advance progress counter if appropriate */
if (cinfo->progress != NULL &&
(retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) {
if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) {
/* startup underestimated number of scans; ratchet up one scan */
cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows;
}
}
}
/* Set state so that jpeg_finish_decompress does the right thing */
cinfo->global_state = DSTATE_STOPPING;
}
/* Set state so that jpeg_finish_decompress does the right thing */
cinfo->global_state = DSTATE_STOPPING;
return cinfo->coef->coef_arrays;
/* At this point we should be in state DSTATE_STOPPING if being used
* standalone, or in state DSTATE_BUFIMAGE if being invoked to get access
* to the coefficients during a full buffered-image-mode decompression.
*/
if ((cinfo->global_state == DSTATE_STOPPING ||
cinfo->global_state == DSTATE_BUFIMAGE) && cinfo->buffered_image) {
return cinfo->coef->coef_arrays;
}
/* Oops, improper usage */
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
return NULL; /* keep compiler happy */
}
@@ -78,9 +96,16 @@ jpeg_read_coefficients (j_decompress_ptr cinfo)
LOCAL(void)
transdecode_master_selection (j_decompress_ptr cinfo)
{
/* This is effectively a buffered-image operation. */
cinfo->buffered_image = TRUE;
/* Entropy decoding: either Huffman or arithmetic coding. */
if (cinfo->arith_code) {
#ifdef D_ARITH_CODING_SUPPORTED
jinit_arith_decoder(cinfo);
#else
ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
#endif
} else {
if (cinfo->progressive_mode) {
#ifdef D_PROGRESSIVE_SUPPORTED

View File

@@ -1,7 +1,7 @@
/*
* jerror.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Copyright (C) 1991-1998, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -10,6 +10,11 @@
* stderr is the right thing to do. Many applications will want to replace
* some or all of these routines.
*
* If you define USE_WINDOWS_MESSAGEBOX in jconfig.h or in the makefile,
* you get a Windows-specific hack to display error messages in a dialog box.
* It ain't much, but it beats dropping error messages into the bit bucket,
* which is what happens to output to stderr under most Windows C compilers.
*
* These routines are used by both the compression and decompression code.
*/
@@ -19,6 +24,10 @@
#include "jversion.h"
#include "jerror.h"
#ifdef USE_WINDOWS_MESSAGEBOX
#include <windows.h>
#endif
#ifndef EXIT_FAILURE /* define exit() codes if not provided */
#define EXIT_FAILURE 1
#endif
@@ -74,6 +83,15 @@ error_exit (j_common_ptr cinfo)
* Actual output of an error or trace message.
* Applications may override this method to send JPEG messages somewhere
* other than stderr.
*
* On Windows, printing to stderr is generally completely useless,
* so we provide optional code to produce an error-dialog popup.
* Most Windows applications will still prefer to override this routine,
* but if they don't, it'll do something at least marginally useful.
*
* NOTE: to use the library in an environment that doesn't support the
* C stdio library, you may have to delete the call to fprintf() entirely,
* not just not use this routine.
*/
METHODDEF(void)
@@ -84,8 +102,14 @@ output_message (j_common_ptr cinfo)
/* Create the message */
(*cinfo->err->format_message) (cinfo, buffer);
#ifdef USE_WINDOWS_MESSAGEBOX
/* Display it in a message dialog box */
MessageBox(GetActiveWindow(), buffer, "JPEG Library Error",
MB_OK | MB_ICONERROR);
#else
/* Send it to stderr, adding a newline */
fprintf(stderr, "%s\n", buffer);
#endif
}

View File

@@ -1,7 +1,8 @@
/*
* jerror.h
*
* Copyright (C) 1994-1995, Thomas G. Lane.
* Copyright (C) 1994-1997, Thomas G. Lane.
* Modified 1997-2009 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -40,12 +41,15 @@ JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */
/* For maintenance convenience, list is alphabetical by message code name */
JMESSAGE(JERR_ARITH_NOTIMPL,
"Sorry, there are legal restrictions on arithmetic coding")
"Sorry, arithmetic coding is not implemented")
JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYPE is wrong, please fix")
JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix")
JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode")
JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS")
JMESSAGE(JERR_BAD_CROP_SPEC, "Invalid crop request")
JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range")
JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported")
JMESSAGE(JERR_BAD_HUFF_TABLE, "Bogus Huffman table definition")
JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace")
JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace")
JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length")
@@ -71,7 +75,6 @@ JMESSAGE(JERR_COMPONENT_COUNT, "Too many color components: %d, max %d")
JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request")
JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d")
JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x")
JMESSAGE(JERR_DHT_COUNTS, "Bogus DHT counts")
JMESSAGE(JERR_DHT_INDEX, "Bogus DHT index %d")
JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d")
JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)")
@@ -92,6 +95,7 @@ JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data")
JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change")
JMESSAGE(JERR_NOTIMPL, "Not implemented yet")
JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time")
JMESSAGE(JERR_NO_ARITH_TABLE, "Arithmetic table 0x%02x was not defined")
JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported")
JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined")
JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image")
@@ -134,12 +138,13 @@ JMESSAGE(JTRC_EMS_CLOSE, "Freed EMS handle %u")
JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u")
JMESSAGE(JTRC_EOI, "End Of Image")
JMESSAGE(JTRC_HUFFBITS, " %3d %3d %3d %3d %3d %3d %3d %3d")
JMESSAGE(JTRC_JFIF, "JFIF APP0 marker, density %dx%d %d")
JMESSAGE(JTRC_JFIF, "JFIF APP0 marker: version %d.%02d, density %dx%d %d")
JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE,
"Warning: thumbnail image size does not match data length %u")
JMESSAGE(JTRC_JFIF_MINOR, "Unknown JFIF minor revision number %d.%02d")
JMESSAGE(JTRC_JFIF_EXTENSION,
"JFIF extension marker: type 0x%02x, length %u")
JMESSAGE(JTRC_JFIF_THUMBNAIL, " with %d x %d thumbnail image")
JMESSAGE(JTRC_MISC_MARKER, "Skipping marker 0x%02x, length %u")
JMESSAGE(JTRC_MISC_MARKER, "Miscellaneous marker 0x%02x, length %u")
JMESSAGE(JTRC_PARMLESS_MARKER, "Unexpected marker 0x%02x")
JMESSAGE(JTRC_QUANTVALS, " %4u %4u %4u %4u %4u %4u %4u %4u")
JMESSAGE(JTRC_QUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors")
@@ -157,11 +162,18 @@ JMESSAGE(JTRC_SOS_COMPONENT, " Component %d: dc=%d ac=%d")
JMESSAGE(JTRC_SOS_PARAMS, " Ss=%d, Se=%d, Ah=%d, Al=%d")
JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s")
JMESSAGE(JTRC_TFILE_OPEN, "Opened temporary file %s")
JMESSAGE(JTRC_THUMB_JPEG,
"JFIF extension marker: JPEG-compressed thumbnail image, length %u")
JMESSAGE(JTRC_THUMB_PALETTE,
"JFIF extension marker: palette thumbnail image, length %u")
JMESSAGE(JTRC_THUMB_RGB,
"JFIF extension marker: RGB thumbnail image, length %u")
JMESSAGE(JTRC_UNKNOWN_IDS,
"Unrecognized component IDs %d %d %d, assuming YCbCr")
JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u")
JMESSAGE(JTRC_XMS_OPEN, "Obtained XMS handle %u")
JMESSAGE(JWRN_ADOBE_XFORM, "Unknown Adobe color transform code %d")
JMESSAGE(JWRN_ARITH_BAD_CODE, "Corrupt JPEG data: bad arithmetic code")
JMESSAGE(JWRN_BOGUS_PROGRESSION,
"Inconsistent progression sequence for component %d coefficient %d")
JMESSAGE(JWRN_EXTRANEOUS_DATA,
@@ -263,6 +275,12 @@ JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines")
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
(cinfo)->err->msg_code = (code); \
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
#define TRACEMS5(cinfo,lvl,code,p1,p2,p3,p4,p5) \
MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
_mp[4] = (p5); \
(cinfo)->err->msg_code = (code); \
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
#define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8) \
MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \

View File

@@ -1,7 +1,7 @@
/*
* jidctflt.c
*
* Copyright (C) 1994-1996, Thomas G. Lane.
* Copyright (C) 1994-1998, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -96,9 +96,10 @@ jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
* column DCT calculations can be simplified this way.
*/
if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*2] | inptr[DCTSIZE*3] |
inptr[DCTSIZE*4] | inptr[DCTSIZE*5] | inptr[DCTSIZE*6] |
inptr[DCTSIZE*7]) == 0) {
if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
inptr[DCTSIZE*7] == 0) {
/* AC terms all zero */
FAST_FLOAT dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);

View File

@@ -1,7 +1,7 @@
/*
* jidctfst.c
*
* Copyright (C) 1994-1996, Thomas G. Lane.
* Copyright (C) 1994-1998, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -197,9 +197,10 @@ jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr,
* column DCT calculations can be simplified this way.
*/
if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*2] | inptr[DCTSIZE*3] |
inptr[DCTSIZE*4] | inptr[DCTSIZE*5] | inptr[DCTSIZE*6] |
inptr[DCTSIZE*7]) == 0) {
if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
inptr[DCTSIZE*7] == 0) {
/* AC terms all zero */
int dcval = (int) DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
@@ -289,8 +290,8 @@ jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr,
*/
#ifndef NO_ZERO_ROW_TEST
if ((wsptr[1] | wsptr[2] | wsptr[3] | wsptr[4] | wsptr[5] | wsptr[6] |
wsptr[7]) == 0) {
if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 &&
wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
/* AC terms all zero */
JSAMPLE dcval = range_limit[IDESCALE(wsptr[0], PASS1_BITS+3)
& RANGE_MASK];

View File

@@ -1,7 +1,7 @@
/*
* jidctint.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Copyright (C) 1991-1998, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -178,9 +178,10 @@ jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr,
* column DCT calculations can be simplified this way.
*/
if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*2] | inptr[DCTSIZE*3] |
inptr[DCTSIZE*4] | inptr[DCTSIZE*5] | inptr[DCTSIZE*6] |
inptr[DCTSIZE*7]) == 0) {
if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
inptr[DCTSIZE*7] == 0) {
/* AC terms all zero */
int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
@@ -284,8 +285,8 @@ jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr,
*/
#ifndef NO_ZERO_ROW_TEST
if ((wsptr[1] | wsptr[2] | wsptr[3] | wsptr[4] | wsptr[5] | wsptr[6] |
wsptr[7]) == 0) {
if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 &&
wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
/* AC terms all zero */
JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
& RANGE_MASK];

View File

@@ -1,7 +1,7 @@
/*
* jidctred.c
*
* Copyright (C) 1994-1996, Thomas G. Lane.
* Copyright (C) 1994-1998, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -139,8 +139,9 @@ jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
/* Don't bother to process column 4, because second pass won't use it */
if (ctr == DCTSIZE-4)
continue;
if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*2] | inptr[DCTSIZE*3] |
inptr[DCTSIZE*5] | inptr[DCTSIZE*6] | inptr[DCTSIZE*7]) == 0) {
if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*5] == 0 &&
inptr[DCTSIZE*6] == 0 && inptr[DCTSIZE*7] == 0) {
/* AC terms all zero; we need not examine term 4 for 4x4 output */
int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
@@ -198,8 +199,8 @@ jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
/* It's not clear whether a zero row test is worthwhile here ... */
#ifndef NO_ZERO_ROW_TEST
if ((wsptr[1] | wsptr[2] | wsptr[3] | wsptr[5] | wsptr[6] |
wsptr[7]) == 0) {
if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 &&
wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
/* AC terms all zero */
JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
& RANGE_MASK];
@@ -290,8 +291,8 @@ jpeg_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
/* Don't bother to process columns 2,4,6 */
if (ctr == DCTSIZE-2 || ctr == DCTSIZE-4 || ctr == DCTSIZE-6)
continue;
if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*3] |
inptr[DCTSIZE*5] | inptr[DCTSIZE*7]) == 0) {
if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*3] == 0 &&
inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*7] == 0) {
/* AC terms all zero; we need not examine terms 2,4,6 for 2x2 output */
int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
@@ -331,7 +332,7 @@ jpeg_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
/* It's not clear whether a zero row test is worthwhile here ... */
#ifndef NO_ZERO_ROW_TEST
if ((wsptr[1] | wsptr[3] | wsptr[5] | wsptr[7]) == 0) {
if (wsptr[1] == 0 && wsptr[3] == 0 && wsptr[5] == 0 && wsptr[7] == 0) {
/* AC terms all zero */
JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
& RANGE_MASK];

View File

@@ -1,167 +0,0 @@
/*
* jmemansi.c
*
* Copyright (C) 1992-1996, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file provides a simple generic implementation of the system-
* dependent portion of the JPEG memory manager. This implementation
* assumes that you have the ANSI-standard library routine tmpfile().
* Also, the problem of determining the amount of memory available
* is shoved onto the user.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jmemsys.h" /* import the system-dependent declarations */
#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare malloc(),free() */
extern void * malloc JPP((size_t size));
extern void free JPP((void *ptr));
#endif
#ifndef SEEK_SET /* pre-ANSI systems may not define this; */
#define SEEK_SET 0 /* if not, assume 0 is correct */
#endif
/*
* Memory allocation and freeing are controlled by the regular library
* routines malloc() and free().
*/
GLOBAL(void *)
jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
{
return (void *) malloc(sizeofobject);
}
GLOBAL(void)
jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
{
free(object);
}
/*
* "Large" objects are treated the same as "small" ones.
* NB: although we include FAR keywords in the routine declarations,
* this file won't actually work in 80x86 small/medium model; at least,
* you probably won't be able to process useful-size images in only 64KB.
*/
GLOBAL(void FAR *)
jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
{
return (void FAR *) malloc(sizeofobject);
}
GLOBAL(void)
jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
{
free(object);
}
/*
* This routine computes the total memory space available for allocation.
* It's impossible to do this in a portable way; our current solution is
* to make the user tell us (with a default value set at compile time).
* If you can actually get the available space, it's a good idea to subtract
* a slop factor of 5% or so.
*/
#ifndef DEFAULT_MAX_MEM /* so can override from makefile */
#define DEFAULT_MAX_MEM 1000000L /* default: one megabyte */
#endif
GLOBAL(long)
jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
long max_bytes_needed, long already_allocated)
{
return cinfo->mem->max_memory_to_use - already_allocated;
}
/*
* Backing store (temporary file) management.
* Backing store objects are only used when the value returned by
* jpeg_mem_available is less than the total space needed. You can dispense
* with these routines if you have plenty of virtual memory; see jmemnobs.c.
*/
METHODDEF(void)
read_backing_store (j_common_ptr cinfo, backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count)
{
if (fseek(info->temp_file, file_offset, SEEK_SET))
ERREXIT(cinfo, JERR_TFILE_SEEK);
if (JFREAD(info->temp_file, buffer_address, byte_count)
!= (size_t) byte_count)
ERREXIT(cinfo, JERR_TFILE_READ);
}
METHODDEF(void)
write_backing_store (j_common_ptr cinfo, backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count)
{
if (fseek(info->temp_file, file_offset, SEEK_SET))
ERREXIT(cinfo, JERR_TFILE_SEEK);
if (JFWRITE(info->temp_file, buffer_address, byte_count)
!= (size_t) byte_count)
ERREXIT(cinfo, JERR_TFILE_WRITE);
}
METHODDEF(void)
close_backing_store (j_common_ptr cinfo, backing_store_ptr info)
{
fclose(info->temp_file);
/* Since this implementation uses tmpfile() to create the file,
* no explicit file deletion is needed.
*/
}
/*
* Initial opening of a backing-store object.
*
* This version uses tmpfile(), which constructs a suitable file name
* behind the scenes. We don't have to use info->temp_name[] at all;
* indeed, we can't even find out the actual name of the temp file.
*/
GLOBAL(void)
jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
long total_bytes_needed)
{
if ((info->temp_file = tmpfile()) == NULL)
ERREXITS(cinfo, JERR_TFILE_CREATE, "");
info->read_backing_store = read_backing_store;
info->write_backing_store = write_backing_store;
info->close_backing_store = close_backing_store;
}
/*
* These routines take care of any system-dependent initialization and
* cleanup required.
*/
GLOBAL(long)
jpeg_mem_init (j_common_ptr cinfo)
{
return DEFAULT_MAX_MEM; /* default for max_memory_to_use */
}
GLOBAL(void)
jpeg_mem_term (j_common_ptr cinfo)
{
/* no work */
}

634
jmemdos.c
View File

@@ -1,634 +0,0 @@
/*
* jmemdos.c
*
* Copyright (C) 1992-1996, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file provides an MS-DOS-compatible implementation of the system-
* dependent portion of the JPEG memory manager. Temporary data can be
* stored in extended or expanded memory as well as in regular DOS files.
*
* If you use this file, you must be sure that NEED_FAR_POINTERS is defined
* if you compile in a small-data memory model; it should NOT be defined if
* you use a large-data memory model. This file is not recommended if you
* are using a flat-memory-space 386 environment such as DJGCC or Watcom C.
* Also, this code will NOT work if struct fields are aligned on greater than
* 2-byte boundaries.
*
* Based on code contributed by Ge' Weijers.
*/
/*
* If you have both extended and expanded memory, you may want to change the
* order in which they are tried in jopen_backing_store. On a 286 machine
* expanded memory is usually faster, since extended memory access involves
* an expensive protected-mode-and-back switch. On 386 and better, extended
* memory is usually faster. As distributed, the code tries extended memory
* first (what? not everyone has a 386? :-).
*
* You can disable use of extended/expanded memory entirely by altering these
* definitions or overriding them from the Makefile (eg, -DEMS_SUPPORTED=0).
*/
#ifndef XMS_SUPPORTED
#define XMS_SUPPORTED 1
#endif
#ifndef EMS_SUPPORTED
#define EMS_SUPPORTED 1
#endif
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jmemsys.h" /* import the system-dependent declarations */
#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare these */
extern void * malloc JPP((size_t size));
extern void free JPP((void *ptr));
extern char * getenv JPP((const char * name));
#endif
#ifdef NEED_FAR_POINTERS
#ifdef __TURBOC__
/* These definitions work for Borland C (Turbo C) */
#include <alloc.h> /* need farmalloc(), farfree() */
#define far_malloc(x) farmalloc(x)
#define far_free(x) farfree(x)
#else
/* These definitions work for Microsoft C and compatible compilers */
#include <malloc.h> /* need _fmalloc(), _ffree() */
#define far_malloc(x) _fmalloc(x)
#define far_free(x) _ffree(x)
#endif
#else /* not NEED_FAR_POINTERS */
#define far_malloc(x) malloc(x)
#define far_free(x) free(x)
#endif /* NEED_FAR_POINTERS */
#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */
#define READ_BINARY "r"
#else
#define READ_BINARY "rb"
#endif
#if MAX_ALLOC_CHUNK >= 65535L /* make sure jconfig.h got this right */
MAX_ALLOC_CHUNK should be less than 64K. /* deliberate syntax error */
#endif
/*
* Declarations for assembly-language support routines (see jmemdosa.asm).
*
* The functions are declared "far" as are all their pointer arguments;
* this ensures the assembly source code will work regardless of the
* compiler memory model. We assume "short" is 16 bits, "long" is 32.
*/
typedef void far * XMSDRIVER; /* actually a pointer to code */
typedef struct { /* registers for calling XMS driver */
unsigned short ax, dx, bx;
void far * ds_si;
} XMScontext;
typedef struct { /* registers for calling EMS driver */
unsigned short ax, dx, bx;
void far * ds_si;
} EMScontext;
extern short far jdos_open JPP((short far * handle, char far * filename));
extern short far jdos_close JPP((short handle));
extern short far jdos_seek JPP((short handle, long offset));
extern short far jdos_read JPP((short handle, void far * buffer,
unsigned short count));
extern short far jdos_write JPP((short handle, void far * buffer,
unsigned short count));
extern void far jxms_getdriver JPP((XMSDRIVER far *));
extern void far jxms_calldriver JPP((XMSDRIVER, XMScontext far *));
extern short far jems_available JPP((void));
extern void far jems_calldriver JPP((EMScontext far *));
/*
* Selection of a file name for a temporary file.
* This is highly system-dependent, and you may want to customize it.
*/
static int next_file_num; /* to distinguish among several temp files */
LOCAL(void)
select_file_name (char * fname)
{
const char * env;
char * ptr;
FILE * tfile;
/* Keep generating file names till we find one that's not in use */
for (;;) {
/* Get temp directory name from environment TMP or TEMP variable;
* if none, use "."
*/
if ((env = (const char *) getenv("TMP")) == NULL)
if ((env = (const char *) getenv("TEMP")) == NULL)
env = ".";
if (*env == '\0') /* null string means "." */
env = ".";
ptr = fname; /* copy name to fname */
while (*env != '\0')
*ptr++ = *env++;
if (ptr[-1] != '\\' && ptr[-1] != '/')
*ptr++ = '\\'; /* append backslash if not in env variable */
/* Append a suitable file name */
next_file_num++; /* advance counter */
sprintf(ptr, "JPG%03d.TMP", next_file_num);
/* Probe to see if file name is already in use */
if ((tfile = fopen(fname, READ_BINARY)) == NULL)
break;
fclose(tfile); /* oops, it's there; close tfile & try again */
}
}
/*
* Near-memory allocation and freeing are controlled by the regular library
* routines malloc() and free().
*/
GLOBAL(void *)
jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
{
return (void *) malloc(sizeofobject);
}
GLOBAL(void)
jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
{
free(object);
}
/*
* "Large" objects are allocated in far memory, if possible
*/
GLOBAL(void FAR *)
jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
{
return (void FAR *) far_malloc(sizeofobject);
}
GLOBAL(void)
jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
{
far_free(object);
}
/*
* This routine computes the total memory space available for allocation.
* It's impossible to do this in a portable way; our current solution is
* to make the user tell us (with a default value set at compile time).
* If you can actually get the available space, it's a good idea to subtract
* a slop factor of 5% or so.
*/
#ifndef DEFAULT_MAX_MEM /* so can override from makefile */
#define DEFAULT_MAX_MEM 300000L /* for total usage about 450K */
#endif
GLOBAL(long)
jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
long max_bytes_needed, long already_allocated)
{
return cinfo->mem->max_memory_to_use - already_allocated;
}
/*
* Backing store (temporary file) management.
* Backing store objects are only used when the value returned by
* jpeg_mem_available is less than the total space needed. You can dispense
* with these routines if you have plenty of virtual memory; see jmemnobs.c.
*/
/*
* For MS-DOS we support three types of backing storage:
* 1. Conventional DOS files. We access these by direct DOS calls rather
* than via the stdio package. This provides a bit better performance,
* but the real reason is that the buffers to be read or written are FAR.
* The stdio library for small-data memory models can't cope with that.
* 2. Extended memory, accessed per the XMS V2.0 specification.
* 3. Expanded memory, accessed per the LIM/EMS 4.0 specification.
* You'll need copies of those specs to make sense of the related code.
* The specs are available by Internet FTP from the SIMTEL archives
* (oak.oakland.edu and its various mirror sites). See files
* pub/msdos/microsoft/xms20.arc and pub/msdos/info/limems41.zip.
*/
/*
* Access methods for a DOS file.
*/
METHODDEF(void)
read_file_store (j_common_ptr cinfo, backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count)
{
if (jdos_seek(info->handle.file_handle, file_offset))
ERREXIT(cinfo, JERR_TFILE_SEEK);
/* Since MAX_ALLOC_CHUNK is less than 64K, byte_count will be too. */
if (byte_count > 65535L) /* safety check */
ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK);
if (jdos_read(info->handle.file_handle, buffer_address,
(unsigned short) byte_count))
ERREXIT(cinfo, JERR_TFILE_READ);
}
METHODDEF(void)
write_file_store (j_common_ptr cinfo, backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count)
{
if (jdos_seek(info->handle.file_handle, file_offset))
ERREXIT(cinfo, JERR_TFILE_SEEK);
/* Since MAX_ALLOC_CHUNK is less than 64K, byte_count will be too. */
if (byte_count > 65535L) /* safety check */
ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK);
if (jdos_write(info->handle.file_handle, buffer_address,
(unsigned short) byte_count))
ERREXIT(cinfo, JERR_TFILE_WRITE);
}
METHODDEF(void)
close_file_store (j_common_ptr cinfo, backing_store_ptr info)
{
jdos_close(info->handle.file_handle); /* close the file */
remove(info->temp_name); /* delete the file */
/* If your system doesn't have remove(), try unlink() instead.
* remove() is the ANSI-standard name for this function, but
* unlink() was more common in pre-ANSI systems.
*/
TRACEMSS(cinfo, 1, JTRC_TFILE_CLOSE, info->temp_name);
}
LOCAL(boolean)
open_file_store (j_common_ptr cinfo, backing_store_ptr info,
long total_bytes_needed)
{
short handle;
select_file_name(info->temp_name);
if (jdos_open((short far *) & handle, (char far *) info->temp_name)) {
/* might as well exit since jpeg_open_backing_store will fail anyway */
ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name);
return FALSE;
}
info->handle.file_handle = handle;
info->read_backing_store = read_file_store;
info->write_backing_store = write_file_store;
info->close_backing_store = close_file_store;
TRACEMSS(cinfo, 1, JTRC_TFILE_OPEN, info->temp_name);
return TRUE; /* succeeded */
}
/*
* Access methods for extended memory.
*/
#if XMS_SUPPORTED
static XMSDRIVER xms_driver; /* saved address of XMS driver */
typedef union { /* either long offset or real-mode pointer */
long offset;
void far * ptr;
} XMSPTR;
typedef struct { /* XMS move specification structure */
long length;
XMSH src_handle;
XMSPTR src;
XMSH dst_handle;
XMSPTR dst;
} XMSspec;
#define ODD(X) (((X) & 1L) != 0)
METHODDEF(void)
read_xms_store (j_common_ptr cinfo, backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count)
{
XMScontext ctx;
XMSspec spec;
char endbuffer[2];
/* The XMS driver can't cope with an odd length, so handle the last byte
* specially if byte_count is odd. We don't expect this to be common.
*/
spec.length = byte_count & (~ 1L);
spec.src_handle = info->handle.xms_handle;
spec.src.offset = file_offset;
spec.dst_handle = 0;
spec.dst.ptr = buffer_address;
ctx.ds_si = (void far *) & spec;
ctx.ax = 0x0b00; /* EMB move */
jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
if (ctx.ax != 1)
ERREXIT(cinfo, JERR_XMS_READ);
if (ODD(byte_count)) {
read_xms_store(cinfo, info, (void FAR *) endbuffer,
file_offset + byte_count - 1L, 2L);
((char FAR *) buffer_address)[byte_count - 1L] = endbuffer[0];
}
}
METHODDEF(void)
write_xms_store (j_common_ptr cinfo, backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count)
{
XMScontext ctx;
XMSspec spec;
char endbuffer[2];
/* The XMS driver can't cope with an odd length, so handle the last byte
* specially if byte_count is odd. We don't expect this to be common.
*/
spec.length = byte_count & (~ 1L);
spec.src_handle = 0;
spec.src.ptr = buffer_address;
spec.dst_handle = info->handle.xms_handle;
spec.dst.offset = file_offset;
ctx.ds_si = (void far *) & spec;
ctx.ax = 0x0b00; /* EMB move */
jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
if (ctx.ax != 1)
ERREXIT(cinfo, JERR_XMS_WRITE);
if (ODD(byte_count)) {
read_xms_store(cinfo, info, (void FAR *) endbuffer,
file_offset + byte_count - 1L, 2L);
endbuffer[0] = ((char FAR *) buffer_address)[byte_count - 1L];
write_xms_store(cinfo, info, (void FAR *) endbuffer,
file_offset + byte_count - 1L, 2L);
}
}
METHODDEF(void)
close_xms_store (j_common_ptr cinfo, backing_store_ptr info)
{
XMScontext ctx;
ctx.dx = info->handle.xms_handle;
ctx.ax = 0x0a00;
jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
TRACEMS1(cinfo, 1, JTRC_XMS_CLOSE, info->handle.xms_handle);
/* we ignore any error return from the driver */
}
LOCAL(boolean)
open_xms_store (j_common_ptr cinfo, backing_store_ptr info,
long total_bytes_needed)
{
XMScontext ctx;
/* Get address of XMS driver */
jxms_getdriver((XMSDRIVER far *) & xms_driver);
if (xms_driver == NULL)
return FALSE; /* no driver to be had */
/* Get version number, must be >= 2.00 */
ctx.ax = 0x0000;
jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
if (ctx.ax < (unsigned short) 0x0200)
return FALSE;
/* Try to get space (expressed in kilobytes) */
ctx.dx = (unsigned short) ((total_bytes_needed + 1023L) >> 10);
ctx.ax = 0x0900;
jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
if (ctx.ax != 1)
return FALSE;
/* Succeeded, save the handle and away we go */
info->handle.xms_handle = ctx.dx;
info->read_backing_store = read_xms_store;
info->write_backing_store = write_xms_store;
info->close_backing_store = close_xms_store;
TRACEMS1(cinfo, 1, JTRC_XMS_OPEN, ctx.dx);
return TRUE; /* succeeded */
}
#endif /* XMS_SUPPORTED */
/*
* Access methods for expanded memory.
*/
#if EMS_SUPPORTED
/* The EMS move specification structure requires word and long fields aligned
* at odd byte boundaries. Some compilers will align struct fields at even
* byte boundaries. While it's usually possible to force byte alignment,
* that causes an overall performance penalty and may pose problems in merging
* JPEG into a larger application. Instead we accept some rather dirty code
* here. Note this code would fail if the hardware did not allow odd-byte
* word & long accesses, but all 80x86 CPUs do.
*/
typedef void far * EMSPTR;
typedef union { /* EMS move specification structure */
long length; /* It's easy to access first 4 bytes */
char bytes[18]; /* Misaligned fields in here! */
} EMSspec;
/* Macros for accessing misaligned fields */
#define FIELD_AT(spec,offset,type) (*((type *) &(spec.bytes[offset])))
#define SRC_TYPE(spec) FIELD_AT(spec,4,char)
#define SRC_HANDLE(spec) FIELD_AT(spec,5,EMSH)
#define SRC_OFFSET(spec) FIELD_AT(spec,7,unsigned short)
#define SRC_PAGE(spec) FIELD_AT(spec,9,unsigned short)
#define SRC_PTR(spec) FIELD_AT(spec,7,EMSPTR)
#define DST_TYPE(spec) FIELD_AT(spec,11,char)
#define DST_HANDLE(spec) FIELD_AT(spec,12,EMSH)
#define DST_OFFSET(spec) FIELD_AT(spec,14,unsigned short)
#define DST_PAGE(spec) FIELD_AT(spec,16,unsigned short)
#define DST_PTR(spec) FIELD_AT(spec,14,EMSPTR)
#define EMSPAGESIZE 16384L /* gospel, see the EMS specs */
#define HIBYTE(W) (((W) >> 8) & 0xFF)
#define LOBYTE(W) ((W) & 0xFF)
METHODDEF(void)
read_ems_store (j_common_ptr cinfo, backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count)
{
EMScontext ctx;
EMSspec spec;
spec.length = byte_count;
SRC_TYPE(spec) = 1;
SRC_HANDLE(spec) = info->handle.ems_handle;
SRC_PAGE(spec) = (unsigned short) (file_offset / EMSPAGESIZE);
SRC_OFFSET(spec) = (unsigned short) (file_offset % EMSPAGESIZE);
DST_TYPE(spec) = 0;
DST_HANDLE(spec) = 0;
DST_PTR(spec) = buffer_address;
ctx.ds_si = (void far *) & spec;
ctx.ax = 0x5700; /* move memory region */
jems_calldriver((EMScontext far *) & ctx);
if (HIBYTE(ctx.ax) != 0)
ERREXIT(cinfo, JERR_EMS_READ);
}
METHODDEF(void)
write_ems_store (j_common_ptr cinfo, backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count)
{
EMScontext ctx;
EMSspec spec;
spec.length = byte_count;
SRC_TYPE(spec) = 0;
SRC_HANDLE(spec) = 0;
SRC_PTR(spec) = buffer_address;
DST_TYPE(spec) = 1;
DST_HANDLE(spec) = info->handle.ems_handle;
DST_PAGE(spec) = (unsigned short) (file_offset / EMSPAGESIZE);
DST_OFFSET(spec) = (unsigned short) (file_offset % EMSPAGESIZE);
ctx.ds_si = (void far *) & spec;
ctx.ax = 0x5700; /* move memory region */
jems_calldriver((EMScontext far *) & ctx);
if (HIBYTE(ctx.ax) != 0)
ERREXIT(cinfo, JERR_EMS_WRITE);
}
METHODDEF(void)
close_ems_store (j_common_ptr cinfo, backing_store_ptr info)
{
EMScontext ctx;
ctx.ax = 0x4500;
ctx.dx = info->handle.ems_handle;
jems_calldriver((EMScontext far *) & ctx);
TRACEMS1(cinfo, 1, JTRC_EMS_CLOSE, info->handle.ems_handle);
/* we ignore any error return from the driver */
}
LOCAL(boolean)
open_ems_store (j_common_ptr cinfo, backing_store_ptr info,
long total_bytes_needed)
{
EMScontext ctx;
/* Is EMS driver there? */
if (! jems_available())
return FALSE;
/* Get status, make sure EMS is OK */
ctx.ax = 0x4000;
jems_calldriver((EMScontext far *) & ctx);
if (HIBYTE(ctx.ax) != 0)
return FALSE;
/* Get version, must be >= 4.0 */
ctx.ax = 0x4600;
jems_calldriver((EMScontext far *) & ctx);
if (HIBYTE(ctx.ax) != 0 || LOBYTE(ctx.ax) < 0x40)
return FALSE;
/* Try to allocate requested space */
ctx.ax = 0x4300;
ctx.bx = (unsigned short) ((total_bytes_needed + EMSPAGESIZE-1L) / EMSPAGESIZE);
jems_calldriver((EMScontext far *) & ctx);
if (HIBYTE(ctx.ax) != 0)
return FALSE;
/* Succeeded, save the handle and away we go */
info->handle.ems_handle = ctx.dx;
info->read_backing_store = read_ems_store;
info->write_backing_store = write_ems_store;
info->close_backing_store = close_ems_store;
TRACEMS1(cinfo, 1, JTRC_EMS_OPEN, ctx.dx);
return TRUE; /* succeeded */
}
#endif /* EMS_SUPPORTED */
/*
* Initial opening of a backing-store object.
*/
GLOBAL(void)
jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
long total_bytes_needed)
{
/* Try extended memory, then expanded memory, then regular file. */
#if XMS_SUPPORTED
if (open_xms_store(cinfo, info, total_bytes_needed))
return;
#endif
#if EMS_SUPPORTED
if (open_ems_store(cinfo, info, total_bytes_needed))
return;
#endif
if (open_file_store(cinfo, info, total_bytes_needed))
return;
ERREXITS(cinfo, JERR_TFILE_CREATE, "");
}
/*
* These routines take care of any system-dependent initialization and
* cleanup required.
*/
GLOBAL(long)
jpeg_mem_init (j_common_ptr cinfo)
{
next_file_num = 0; /* initialize temp file name generator */
return DEFAULT_MAX_MEM; /* default for max_memory_to_use */
}
GLOBAL(void)
jpeg_mem_term (j_common_ptr cinfo)
{
/* Microsoft C, at least in v6.00A, will not successfully reclaim freed
* blocks of size > 32Kbytes unless we give it a kick in the rear, like so:
*/
#ifdef NEED_FHEAPMIN
_fheapmin();
#endif
}

View File

@@ -1,379 +0,0 @@
;
; jmemdosa.asm
;
; Copyright (C) 1992, Thomas G. Lane.
; This file is part of the Independent JPEG Group's software.
; For conditions of distribution and use, see the accompanying README file.
;
; This file contains low-level interface routines to support the MS-DOS
; backing store manager (jmemdos.c). Routines are provided to access disk
; files through direct DOS calls, and to access XMS and EMS drivers.
;
; This file should assemble with Microsoft's MASM or any compatible
; assembler (including Borland's Turbo Assembler). If you haven't got
; a compatible assembler, better fall back to jmemansi.c or jmemname.c.
;
; To minimize dependence on the C compiler's register usage conventions,
; we save and restore all 8086 registers, even though most compilers only
; require SI,DI,DS to be preserved. Also, we use only 16-bit-wide return
; values, which everybody returns in AX.
;
; Based on code contributed by Ge' Weijers.
;
JMEMDOSA_TXT segment byte public 'CODE'
assume cs:JMEMDOSA_TXT
public _jdos_open
public _jdos_close
public _jdos_seek
public _jdos_read
public _jdos_write
public _jxms_getdriver
public _jxms_calldriver
public _jems_available
public _jems_calldriver
;
; short far jdos_open (short far * handle, char far * filename)
;
; Create and open a temporary file
;
_jdos_open proc far
push bp ; linkage
mov bp,sp
push si ; save all registers for safety
push di
push bx
push cx
push dx
push es
push ds
mov cx,0 ; normal file attributes
lds dx,dword ptr [bp+10] ; get filename pointer
mov ah,3ch ; create file
int 21h
jc open_err ; if failed, return error code
lds bx,dword ptr [bp+6] ; get handle pointer
mov word ptr [bx],ax ; save the handle
xor ax,ax ; return zero for OK
open_err: pop ds ; restore registers and exit
pop es
pop dx
pop cx
pop bx
pop di
pop si
pop bp
ret
_jdos_open endp
;
; short far jdos_close (short handle)
;
; Close the file handle
;
_jdos_close proc far
push bp ; linkage
mov bp,sp
push si ; save all registers for safety
push di
push bx
push cx
push dx
push es
push ds
mov bx,word ptr [bp+6] ; file handle
mov ah,3eh ; close file
int 21h
jc close_err ; if failed, return error code
xor ax,ax ; return zero for OK
close_err: pop ds ; restore registers and exit
pop es
pop dx
pop cx
pop bx
pop di
pop si
pop bp
ret
_jdos_close endp
;
; short far jdos_seek (short handle, long offset)
;
; Set file position
;
_jdos_seek proc far
push bp ; linkage
mov bp,sp
push si ; save all registers for safety
push di
push bx
push cx
push dx
push es
push ds
mov bx,word ptr [bp+6] ; file handle
mov dx,word ptr [bp+8] ; LS offset
mov cx,word ptr [bp+10] ; MS offset
mov ax,4200h ; absolute seek
int 21h
jc seek_err ; if failed, return error code
xor ax,ax ; return zero for OK
seek_err: pop ds ; restore registers and exit
pop es
pop dx
pop cx
pop bx
pop di
pop si
pop bp
ret
_jdos_seek endp
;
; short far jdos_read (short handle, void far * buffer, unsigned short count)
;
; Read from file
;
_jdos_read proc far
push bp ; linkage
mov bp,sp
push si ; save all registers for safety
push di
push bx
push cx
push dx
push es
push ds
mov bx,word ptr [bp+6] ; file handle
lds dx,dword ptr [bp+8] ; buffer address
mov cx,word ptr [bp+12] ; number of bytes
mov ah,3fh ; read file
int 21h
jc read_err ; if failed, return error code
cmp ax,word ptr [bp+12] ; make sure all bytes were read
je read_ok
mov ax,1 ; else return 1 for not OK
jmp short read_err
read_ok: xor ax,ax ; return zero for OK
read_err: pop ds ; restore registers and exit
pop es
pop dx
pop cx
pop bx
pop di
pop si
pop bp
ret
_jdos_read endp
;
; short far jdos_write (short handle, void far * buffer, unsigned short count)
;
; Write to file
;
_jdos_write proc far
push bp ; linkage
mov bp,sp
push si ; save all registers for safety
push di
push bx
push cx
push dx
push es
push ds
mov bx,word ptr [bp+6] ; file handle
lds dx,dword ptr [bp+8] ; buffer address
mov cx,word ptr [bp+12] ; number of bytes
mov ah,40h ; write file
int 21h
jc write_err ; if failed, return error code
cmp ax,word ptr [bp+12] ; make sure all bytes written
je write_ok
mov ax,1 ; else return 1 for not OK
jmp short write_err
write_ok: xor ax,ax ; return zero for OK
write_err: pop ds ; restore registers and exit
pop es
pop dx
pop cx
pop bx
pop di
pop si
pop bp
ret
_jdos_write endp
;
; void far jxms_getdriver (XMSDRIVER far *)
;
; Get the address of the XMS driver, or NULL if not available
;
_jxms_getdriver proc far
push bp ; linkage
mov bp,sp
push si ; save all registers for safety
push di
push bx
push cx
push dx
push es
push ds
mov ax,4300h ; call multiplex interrupt with
int 2fh ; a magic cookie, hex 4300
cmp al,80h ; AL should contain hex 80
je xmsavail
xor dx,dx ; no XMS driver available
xor ax,ax ; return a nil pointer
jmp short xmsavail_done
xmsavail: mov ax,4310h ; fetch driver address with
int 2fh ; another magic cookie
mov dx,es ; copy address to dx:ax
mov ax,bx
xmsavail_done: les bx,dword ptr [bp+6] ; get pointer to return value
mov word ptr es:[bx],ax
mov word ptr es:[bx+2],dx
pop ds ; restore registers and exit
pop es
pop dx
pop cx
pop bx
pop di
pop si
pop bp
ret
_jxms_getdriver endp
;
; void far jxms_calldriver (XMSDRIVER, XMScontext far *)
;
; The XMScontext structure contains values for the AX,DX,BX,SI,DS registers.
; These are loaded, the XMS call is performed, and the new values of the
; AX,DX,BX registers are written back to the context structure.
;
_jxms_calldriver proc far
push bp ; linkage
mov bp,sp
push si ; save all registers for safety
push di
push bx
push cx
push dx
push es
push ds
les bx,dword ptr [bp+10] ; get XMScontext pointer
mov ax,word ptr es:[bx] ; load registers
mov dx,word ptr es:[bx+2]
mov si,word ptr es:[bx+6]
mov ds,word ptr es:[bx+8]
mov bx,word ptr es:[bx+4]
call dword ptr [bp+6] ; call the driver
mov cx,bx ; save returned BX for a sec
les bx,dword ptr [bp+10] ; get XMScontext pointer
mov word ptr es:[bx],ax ; put back ax,dx,bx
mov word ptr es:[bx+2],dx
mov word ptr es:[bx+4],cx
pop ds ; restore registers and exit
pop es
pop dx
pop cx
pop bx
pop di
pop si
pop bp
ret
_jxms_calldriver endp
;
; short far jems_available (void)
;
; Have we got an EMS driver? (this comes straight from the EMS 4.0 specs)
;
_jems_available proc far
push si ; save all registers for safety
push di
push bx
push cx
push dx
push es
push ds
mov ax,3567h ; get interrupt vector 67h
int 21h
push cs
pop ds
mov di,000ah ; check offs 10 in returned seg
lea si,ASCII_device_name ; against literal string
mov cx,8
cld
repe cmpsb
jne no_ems
mov ax,1 ; match, it's there
jmp short avail_done
no_ems: xor ax,ax ; it's not there
avail_done: pop ds ; restore registers and exit
pop es
pop dx
pop cx
pop bx
pop di
pop si
ret
ASCII_device_name db "EMMXXXX0"
_jems_available endp
;
; void far jems_calldriver (EMScontext far *)
;
; The EMScontext structure contains values for the AX,DX,BX,SI,DS registers.
; These are loaded, the EMS trap is performed, and the new values of the
; AX,DX,BX registers are written back to the context structure.
;
_jems_calldriver proc far
push bp ; linkage
mov bp,sp
push si ; save all registers for safety
push di
push bx
push cx
push dx
push es
push ds
les bx,dword ptr [bp+6] ; get EMScontext pointer
mov ax,word ptr es:[bx] ; load registers
mov dx,word ptr es:[bx+2]
mov si,word ptr es:[bx+6]
mov ds,word ptr es:[bx+8]
mov bx,word ptr es:[bx+4]
int 67h ; call the EMS driver
mov cx,bx ; save returned BX for a sec
les bx,dword ptr [bp+6] ; get EMScontext pointer
mov word ptr es:[bx],ax ; put back ax,dx,bx
mov word ptr es:[bx+2],dx
mov word ptr es:[bx+4],cx
pop ds ; restore registers and exit
pop es
pop dx
pop cx
pop bx
pop di
pop si
pop bp
ret
_jems_calldriver endp
JMEMDOSA_TXT ends
end

199
jmemmac.c
View File

@@ -1,199 +0,0 @@
/*
* jmemmac.c
*
* Copyright (C) 1992-1996, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* jmemmac.c provides an Apple Macintosh implementation of the system-
* dependent portion of the JPEG memory manager.
*
* jmemmac.c uses the Macintosh toolbox routines NewPtr and DisposePtr
* instead of malloc and free. It accurately determines the amount of
* memory available by using CompactMem. Notice that if left to its
* own devices, this code can chew up all available space in the
* application's zone, with the exception of the rather small "slop"
* factor computed in jpeg_mem_available(). The application can ensure
* that more space is left over by reducing max_memory_to_use.
*
* Large images are swapped to disk using temporary files created with
* tmpfile(); that part of the module is the same as in jmemansi.c.
* Metrowerks CodeWarrior's implementation of tmpfile() isn't quite what
* we want: it puts the files in the local directory and makes them
* user-visible -- and only deletes them when the application quits,
* which means they stick around in the event of a crash.
* It would be better to create the temp files in the system's temporary
* items folder. Perhaps someday we'll get around to doing that.
*
* Contributed by Sam Bushell (jsam@iagu.on.net).
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jmemsys.h" /* import the system-dependent declarations */
#include <Memory.h> /* we use the MacOS memory manager */
#ifndef SEEK_SET /* pre-ANSI systems may not define this; */
#define SEEK_SET 0 /* if not, assume 0 is correct */
#endif
/*
* Memory allocation and freeing are controlled by the MacOS library
* routines NewPtr() and DisposePtr(), which allocate fixed-address
* storage. Unfortunately, the IJG library isn't smart enough to cope
* with relocatable storage.
*/
GLOBAL(void *)
jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
{
return (void *) NewPtr(sizeofobject);
}
GLOBAL(void)
jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
{
DisposePtr((Ptr) object);
}
/*
* "Large" objects are treated the same as "small" ones.
* NB: we include FAR keywords in the routine declarations simply for
* consistency with the rest of the IJG code; FAR should expand to empty
* on rational architectures like the Mac.
*/
GLOBAL(void FAR *)
jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
{
return (void FAR *) NewPtr(sizeofobject);
}
GLOBAL(void)
jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
{
DisposePtr((Ptr) object);
}
/*
* This routine computes the total memory space available for allocation.
*/
GLOBAL(long)
jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
long max_bytes_needed, long already_allocated)
{
long limit = cinfo->mem->max_memory_to_use - already_allocated;
long slop, mem;
/* Don't ask for more than what application has told us we may use */
if (max_bytes_needed > limit && limit > 0)
max_bytes_needed = limit;
/* Find whether there's a big enough free block in the heap.
* CompactMem tries to create a contiguous block of the requested size,
* and then returns the size of the largest free block (which could be
* much more or much less than we asked for).
* We add some slop to ensure we don't use up all available memory.
*/
slop = max_bytes_needed / 16 + 32768L;
mem = CompactMem(max_bytes_needed + slop) - slop;
if (mem < 0)
mem = 0; /* sigh, couldn't even get the slop */
/* Don't take more than the application says we can have */
if (mem > limit && limit > 0)
mem = limit;
return mem;
}
/*
* Backing store (temporary file) management.
* Backing store objects are only used when the value returned by
* jpeg_mem_available is less than the total space needed. You can dispense
* with these routines if you have plenty of virtual memory; see jmemnobs.c.
*/
METHODDEF(void)
read_backing_store (j_common_ptr cinfo, backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count)
{
if (fseek(info->temp_file, file_offset, SEEK_SET))
ERREXIT(cinfo, JERR_TFILE_SEEK);
if (JFREAD(info->temp_file, buffer_address, byte_count)
!= (size_t) byte_count)
ERREXIT(cinfo, JERR_TFILE_READ);
}
METHODDEF(void)
write_backing_store (j_common_ptr cinfo, backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count)
{
if (fseek(info->temp_file, file_offset, SEEK_SET))
ERREXIT(cinfo, JERR_TFILE_SEEK);
if (JFWRITE(info->temp_file, buffer_address, byte_count)
!= (size_t) byte_count)
ERREXIT(cinfo, JERR_TFILE_WRITE);
}
METHODDEF(void)
close_backing_store (j_common_ptr cinfo, backing_store_ptr info)
{
fclose(info->temp_file);
/* Since this implementation uses tmpfile() to create the file,
* no explicit file deletion is needed.
*/
}
/*
* Initial opening of a backing-store object.
*
* This version uses tmpfile(), which constructs a suitable file name
* behind the scenes. We don't have to use info->temp_name[] at all;
* indeed, we can't even find out the actual name of the temp file.
*/
GLOBAL(void)
jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
long total_bytes_needed)
{
if ((info->temp_file = tmpfile()) == NULL)
ERREXITS(cinfo, JERR_TFILE_CREATE, "");
info->read_backing_store = read_backing_store;
info->write_backing_store = write_backing_store;
info->close_backing_store = close_backing_store;
}
/*
* These routines take care of any system-dependent initialization and
* cleanup required.
*/
GLOBAL(long)
jpeg_mem_init (j_common_ptr cinfo)
{
/* max_memory_to_use will be initialized to FreeMem()'s result;
* the calling application might later reduce it, for example
* to leave room to invoke multiple JPEG objects.
* Note that FreeMem returns the total number of free bytes;
* it may not be possible to allocate a single block of this size.
*/
return FreeMem();
}
GLOBAL(void)
jpeg_mem_term (j_common_ptr cinfo)
{
/* no work */
}

179
jmemmgr.c
View File

@@ -1,7 +1,7 @@
/*
* jmemmgr.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Copyright (C) 1991-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -57,22 +57,25 @@ extern char * getenv JPP((const char * name));
* requirement, and we had better do so too.
* There isn't any really portable way to determine the worst-case alignment
* requirement. This module assumes that the alignment requirement is
* multiples of sizeof(ALIGN_TYPE).
* By default, we define ALIGN_TYPE as double. This is necessary on some
* multiples of ALIGN_SIZE.
* By default, we define ALIGN_SIZE as sizeof(double). This is necessary on some
* workstations (where doubles really do need 8-byte alignment) and will work
* fine on nearly everything. If your machine has lesser alignment needs,
* you can save a few bytes by making ALIGN_TYPE smaller.
* you can save a few bytes by making ALIGN_SIZE smaller.
* The only place I know of where this will NOT work is certain Macintosh
* 680x0 compilers that define double as a 10-byte IEEE extended float.
* Doing 10-byte alignment is counterproductive because longwords won't be
* aligned well. Put "#define ALIGN_TYPE long" in jconfig.h if you have
* aligned well. Put "#define ALIGN_SIZE 4" in jconfig.h if you have
* such a compiler.
*/
#ifndef ALIGN_TYPE /* so can override from jconfig.h */
#define ALIGN_TYPE double
#ifndef ALIGN_SIZE /* so can override from jconfig.h */
#ifndef WITH_SIMD
#define ALIGN_SIZE SIZEOF(double)
#else
#define ALIGN_SIZE 16 /* Most SIMD implementations require this */
#endif
#endif
/*
* We allocate objects from "pools", where each pool is gotten with a single
@@ -81,34 +84,24 @@ extern char * getenv JPP((const char * name));
* header with a link to the next pool of the same class.
* Small and large pool headers are identical except that the latter's
* link pointer must be FAR on 80x86 machines.
* Notice that the "real" header fields are union'ed with a dummy ALIGN_TYPE
* field. This forces the compiler to make SIZEOF(small_pool_hdr) a multiple
* of the alignment requirement of ALIGN_TYPE.
*/
typedef union small_pool_struct * small_pool_ptr;
typedef struct small_pool_struct * small_pool_ptr;
typedef union small_pool_struct {
struct {
small_pool_ptr next; /* next in list of pools */
size_t bytes_used; /* how many bytes already used within pool */
size_t bytes_left; /* bytes still available in this pool */
} hdr;
ALIGN_TYPE dummy; /* included in union to ensure alignment */
typedef struct small_pool_struct {
small_pool_ptr next; /* next in list of pools */
size_t bytes_used; /* how many bytes already used within pool */
size_t bytes_left; /* bytes still available in this pool */
} small_pool_hdr;
typedef union large_pool_struct FAR * large_pool_ptr;
typedef struct large_pool_struct FAR * large_pool_ptr;
typedef union large_pool_struct {
struct {
large_pool_ptr next; /* next in list of pools */
size_t bytes_used; /* how many bytes already used within pool */
size_t bytes_left; /* bytes still available in this pool */
} hdr;
ALIGN_TYPE dummy; /* included in union to ensure alignment */
typedef struct large_pool_struct {
large_pool_ptr next; /* next in list of pools */
size_t bytes_used; /* how many bytes already used within pool */
size_t bytes_left; /* bytes still available in this pool */
} large_pool_hdr;
/*
* Here is the full definition of a memory manager object.
*/
@@ -129,7 +122,7 @@ typedef struct {
jvirt_barray_ptr virt_barray_list;
/* This counts total space obtained from jpeg_get_small/large */
long total_space_allocated;
size_t total_space_allocated;
/* alloc_sarray and alloc_barray set this value for use by virtual
* array routines.
@@ -197,16 +190,16 @@ print_mem_stats (j_common_ptr cinfo, int pool_id)
pool_id, mem->total_space_allocated);
for (lhdr_ptr = mem->large_list[pool_id]; lhdr_ptr != NULL;
lhdr_ptr = lhdr_ptr->hdr.next) {
lhdr_ptr = lhdr_ptr->next) {
fprintf(stderr, " Large chunk used %ld\n",
(long) lhdr_ptr->hdr.bytes_used);
(long) lhdr_ptr->bytes_used);
}
for (shdr_ptr = mem->small_list[pool_id]; shdr_ptr != NULL;
shdr_ptr = shdr_ptr->hdr.next) {
shdr_ptr = shdr_ptr->next) {
fprintf(stderr, " Small chunk used %ld free %ld\n",
(long) shdr_ptr->hdr.bytes_used,
(long) shdr_ptr->hdr.bytes_left);
(long) shdr_ptr->bytes_used,
(long) shdr_ptr->bytes_left);
}
}
@@ -236,6 +229,10 @@ out_of_memory (j_common_ptr cinfo, int which)
* and we also distinguish the first pool of a class from later ones.
* NOTE: the values given work fairly well on both 16- and 32-bit-int
* machines, but may be too small if longs are 64 bits or more.
*
* Since we do not know what alignment malloc() gives us, we have to
* allocate ALIGN_SIZE-1 extra space per pool to have room for alignment
* adjustment.
*/
static const size_t first_pool_slop[JPOOL_NUMPOOLS] =
@@ -260,33 +257,36 @@ alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
small_pool_ptr hdr_ptr, prev_hdr_ptr;
char * data_ptr;
size_t odd_bytes, min_request, slop;
size_t min_request, slop;
/*
* Round up the requested size to a multiple of ALIGN_SIZE in order
* to assure alignment for the next object allocated in the same pool
* and so that algorithms can straddle outside the proper area up
* to the next alignment.
*/
sizeofobject = jround_up(sizeofobject, ALIGN_SIZE);
/* Check for unsatisfiable request (do now to ensure no overflow below) */
if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(small_pool_hdr)))
if ((SIZEOF(small_pool_hdr) + sizeofobject + ALIGN_SIZE - 1) > MAX_ALLOC_CHUNK)
out_of_memory(cinfo, 1); /* request exceeds malloc's ability */
/* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */
odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE);
if (odd_bytes > 0)
sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes;
/* See if space is available in any existing pool */
if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
prev_hdr_ptr = NULL;
hdr_ptr = mem->small_list[pool_id];
while (hdr_ptr != NULL) {
if (hdr_ptr->hdr.bytes_left >= sizeofobject)
if (hdr_ptr->bytes_left >= sizeofobject)
break; /* found pool with enough space */
prev_hdr_ptr = hdr_ptr;
hdr_ptr = hdr_ptr->hdr.next;
hdr_ptr = hdr_ptr->next;
}
/* Time to make a new pool? */
if (hdr_ptr == NULL) {
/* min_request is what we need now, slop is what will be leftover */
min_request = sizeofobject + SIZEOF(small_pool_hdr);
min_request = SIZEOF(small_pool_hdr) + sizeofobject + ALIGN_SIZE - 1;
if (prev_hdr_ptr == NULL) /* first pool in class? */
slop = first_pool_slop[pool_id];
else
@@ -305,20 +305,23 @@ alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
}
mem->total_space_allocated += min_request + slop;
/* Success, initialize the new pool header and add to end of list */
hdr_ptr->hdr.next = NULL;
hdr_ptr->hdr.bytes_used = 0;
hdr_ptr->hdr.bytes_left = sizeofobject + slop;
hdr_ptr->next = NULL;
hdr_ptr->bytes_used = 0;
hdr_ptr->bytes_left = sizeofobject + slop;
if (prev_hdr_ptr == NULL) /* first pool in class? */
mem->small_list[pool_id] = hdr_ptr;
else
prev_hdr_ptr->hdr.next = hdr_ptr;
prev_hdr_ptr->next = hdr_ptr;
}
/* OK, allocate the object from the current pool */
data_ptr = (char *) (hdr_ptr + 1); /* point to first data byte in pool */
data_ptr += hdr_ptr->hdr.bytes_used; /* point to place for object */
hdr_ptr->hdr.bytes_used += sizeofobject;
hdr_ptr->hdr.bytes_left -= sizeofobject;
data_ptr = (char *) hdr_ptr; /* point to first data byte in pool... */
data_ptr += SIZEOF(small_pool_hdr); /* ...by skipping the header... */
if ((size_t)data_ptr % ALIGN_SIZE) /* ...and adjust for alignment */
data_ptr += ALIGN_SIZE - (size_t)data_ptr % ALIGN_SIZE;
data_ptr += hdr_ptr->bytes_used; /* point to place for object */
hdr_ptr->bytes_used += sizeofobject;
hdr_ptr->bytes_left -= sizeofobject;
return (void *) data_ptr;
}
@@ -344,37 +347,45 @@ alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
{
my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
large_pool_ptr hdr_ptr;
size_t odd_bytes;
char FAR * data_ptr;
/*
* Round up the requested size to a multiple of ALIGN_SIZE so that
* algorithms can straddle outside the proper area up to the next
* alignment.
*/
sizeofobject = jround_up(sizeofobject, ALIGN_SIZE);
/* Check for unsatisfiable request (do now to ensure no overflow below) */
if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)))
if ((SIZEOF(large_pool_hdr) + sizeofobject + ALIGN_SIZE - 1) > MAX_ALLOC_CHUNK)
out_of_memory(cinfo, 3); /* request exceeds malloc's ability */
/* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */
odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE);
if (odd_bytes > 0)
sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes;
/* Always make a new pool */
if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
hdr_ptr = (large_pool_ptr) jpeg_get_large(cinfo, sizeofobject +
SIZEOF(large_pool_hdr));
SIZEOF(large_pool_hdr) +
ALIGN_SIZE - 1);
if (hdr_ptr == NULL)
out_of_memory(cinfo, 4); /* jpeg_get_large failed */
mem->total_space_allocated += sizeofobject + SIZEOF(large_pool_hdr);
mem->total_space_allocated += sizeofobject + SIZEOF(large_pool_hdr) + ALIGN_SIZE - 1;
/* Success, initialize the new pool header and add to list */
hdr_ptr->hdr.next = mem->large_list[pool_id];
hdr_ptr->next = mem->large_list[pool_id];
/* We maintain space counts in each pool header for statistical purposes,
* even though they are not needed for allocation.
*/
hdr_ptr->hdr.bytes_used = sizeofobject;
hdr_ptr->hdr.bytes_left = 0;
hdr_ptr->bytes_used = sizeofobject;
hdr_ptr->bytes_left = 0;
mem->large_list[pool_id] = hdr_ptr;
return (void FAR *) (hdr_ptr + 1); /* point to first data byte in pool */
data_ptr = (char *) hdr_ptr; /* point to first data byte in pool... */
data_ptr += SIZEOF(small_pool_hdr); /* ...by skipping the header... */
if ((size_t)data_ptr % ALIGN_SIZE) /* ...and adjust for alignment */
data_ptr += ALIGN_SIZE - (size_t)data_ptr % ALIGN_SIZE;
return (void FAR *) data_ptr;
}
@@ -389,6 +400,10 @@ alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
* this chunking of rows. The rowsperchunk value is left in the mem manager
* object so that it can be saved away if this sarray is the workspace for
* a virtual array.
*
* Since we are often upsampling with a factor 2, we align the size (not
* the start) to 2 * ALIGN_SIZE so that the upsampling routines don't have
* to be as careful about size.
*/
METHODDEF(JSAMPARRAY)
@@ -402,6 +417,11 @@ alloc_sarray (j_common_ptr cinfo, int pool_id,
JDIMENSION rowsperchunk, currow, i;
long ltemp;
/* Make sure each row is properly aligned */
if ((ALIGN_SIZE % SIZEOF(JSAMPLE)) != 0)
out_of_memory(cinfo, 5); /* safety check */
samplesperrow = (JDIMENSION)jround_up(samplesperrow, (2 * ALIGN_SIZE) / SIZEOF(JSAMPLE));
/* Calculate max # of rows allowed in one allocation chunk */
ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
((long) samplesperrow * SIZEOF(JSAMPLE));
@@ -450,6 +470,10 @@ alloc_barray (j_common_ptr cinfo, int pool_id,
JDIMENSION rowsperchunk, currow, i;
long ltemp;
/* Make sure each row is properly aligned */
if ((SIZEOF(JBLOCK) % ALIGN_SIZE) != 0)
out_of_memory(cinfo, 6); /* safety check */
/* Calculate max # of rows allowed in one allocation chunk */
ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
((long) blocksperrow * SIZEOF(JBLOCK));
@@ -584,8 +608,8 @@ realize_virt_arrays (j_common_ptr cinfo)
/* Allocate the in-memory buffers for any unrealized virtual arrays */
{
my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
long space_per_minheight, maximum_space, avail_mem;
long minheights, max_minheights;
size_t space_per_minheight, maximum_space, avail_mem;
size_t minheights, max_minheights;
jvirt_sarray_ptr sptr;
jvirt_barray_ptr bptr;
@@ -968,9 +992,9 @@ free_pool (j_common_ptr cinfo, int pool_id)
mem->large_list[pool_id] = NULL;
while (lhdr_ptr != NULL) {
large_pool_ptr next_lhdr_ptr = lhdr_ptr->hdr.next;
space_freed = lhdr_ptr->hdr.bytes_used +
lhdr_ptr->hdr.bytes_left +
large_pool_ptr next_lhdr_ptr = lhdr_ptr->next;
space_freed = lhdr_ptr->bytes_used +
lhdr_ptr->bytes_left +
SIZEOF(large_pool_hdr);
jpeg_free_large(cinfo, (void FAR *) lhdr_ptr, space_freed);
mem->total_space_allocated -= space_freed;
@@ -982,9 +1006,9 @@ free_pool (j_common_ptr cinfo, int pool_id)
mem->small_list[pool_id] = NULL;
while (shdr_ptr != NULL) {
small_pool_ptr next_shdr_ptr = shdr_ptr->hdr.next;
space_freed = shdr_ptr->hdr.bytes_used +
shdr_ptr->hdr.bytes_left +
small_pool_ptr next_shdr_ptr = shdr_ptr->next;
space_freed = shdr_ptr->bytes_used +
shdr_ptr->bytes_left +
SIZEOF(small_pool_hdr);
jpeg_free_small(cinfo, (void *) shdr_ptr, space_freed);
mem->total_space_allocated -= space_freed;
@@ -1041,16 +1065,16 @@ jinit_memory_mgr (j_common_ptr cinfo)
* in common if and only if X is a power of 2, ie has only one one-bit.
* Some compilers may give an "unreachable code" warning here; ignore it.
*/
if ((SIZEOF(ALIGN_TYPE) & (SIZEOF(ALIGN_TYPE)-1)) != 0)
if ((ALIGN_SIZE & (ALIGN_SIZE-1)) != 0)
ERREXIT(cinfo, JERR_BAD_ALIGN_TYPE);
/* MAX_ALLOC_CHUNK must be representable as type size_t, and must be
* a multiple of SIZEOF(ALIGN_TYPE).
* a multiple of ALIGN_SIZE.
* Again, an "unreachable code" warning may be ignored here.
* But a "constant too large" warning means you need to fix MAX_ALLOC_CHUNK.
*/
test_mac = (size_t) MAX_ALLOC_CHUNK;
if ((long) test_mac != MAX_ALLOC_CHUNK ||
(MAX_ALLOC_CHUNK % SIZEOF(ALIGN_TYPE)) != 0)
(MAX_ALLOC_CHUNK % ALIGN_SIZE) != 0)
ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK);
max_to_use = jpeg_mem_init(cinfo); /* system-dependent initialization */
@@ -1076,6 +1100,9 @@ jinit_memory_mgr (j_common_ptr cinfo)
mem->pub.free_pool = free_pool;
mem->pub.self_destruct = self_destruct;
/* Make MAX_ALLOC_CHUNK accessible to other modules */
mem->pub.max_alloc_chunk = MAX_ALLOC_CHUNK;
/* Initialize working state */
mem->pub.max_memory_to_use = max_to_use;

View File

@@ -1,271 +0,0 @@
/*
* jmemname.c
*
* Copyright (C) 1992-1996, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file provides a generic implementation of the system-dependent
* portion of the JPEG memory manager. This implementation assumes that
* you must explicitly construct a name for each temp file.
* Also, the problem of determining the amount of memory available
* is shoved onto the user.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jmemsys.h" /* import the system-dependent declarations */
#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare malloc(),free() */
extern void * malloc JPP((size_t size));
extern void free JPP((void *ptr));
#endif
#ifndef SEEK_SET /* pre-ANSI systems may not define this; */
#define SEEK_SET 0 /* if not, assume 0 is correct */
#endif
#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */
#define READ_BINARY "r"
#define RW_BINARY "w+"
#else
#define READ_BINARY "rb"
#define RW_BINARY "w+b"
#endif
/*
* Selection of a file name for a temporary file.
* This is system-dependent!
*
* The code as given is suitable for most Unix systems, and it is easily
* modified for most non-Unix systems. Some notes:
* 1. The temp file is created in the directory named by TEMP_DIRECTORY.
* The default value is /usr/tmp, which is the conventional place for
* creating large temp files on Unix. On other systems you'll probably
* want to change the file location. You can do this by editing the
* #define, or (preferred) by defining TEMP_DIRECTORY in jconfig.h.
*
* 2. If you need to change the file name as well as its location,
* you can override the TEMP_FILE_NAME macro. (Note that this is
* actually a printf format string; it must contain %s and %d.)
* Few people should need to do this.
*
* 3. mktemp() is used to ensure that multiple processes running
* simultaneously won't select the same file names. If your system
* doesn't have mktemp(), define NO_MKTEMP to do it the hard way.
* (If you don't have <errno.h>, also define NO_ERRNO_H.)
*
* 4. You probably want to define NEED_SIGNAL_CATCHER so that cjpeg.c/djpeg.c
* will cause the temp files to be removed if you stop the program early.
*/
#ifndef TEMP_DIRECTORY /* can override from jconfig.h or Makefile */
#define TEMP_DIRECTORY "/usr/tmp/" /* recommended setting for Unix */
#endif
static int next_file_num; /* to distinguish among several temp files */
#ifdef NO_MKTEMP
#ifndef TEMP_FILE_NAME /* can override from jconfig.h or Makefile */
#define TEMP_FILE_NAME "%sJPG%03d.TMP"
#endif
#ifndef NO_ERRNO_H
#include <errno.h> /* to define ENOENT */
#endif
/* ANSI C specifies that errno is a macro, but on older systems it's more
* likely to be a plain int variable. And not all versions of errno.h
* bother to declare it, so we have to in order to be most portable. Thus:
*/
#ifndef errno
extern int errno;
#endif
LOCAL(void)
select_file_name (char * fname)
{
FILE * tfile;
/* Keep generating file names till we find one that's not in use */
for (;;) {
next_file_num++; /* advance counter */
sprintf(fname, TEMP_FILE_NAME, TEMP_DIRECTORY, next_file_num);
if ((tfile = fopen(fname, READ_BINARY)) == NULL) {
/* fopen could have failed for a reason other than the file not
* being there; for example, file there but unreadable.
* If <errno.h> isn't available, then we cannot test the cause.
*/
#ifdef ENOENT
if (errno != ENOENT)
continue;
#endif
break;
}
fclose(tfile); /* oops, it's there; close tfile & try again */
}
}
#else /* ! NO_MKTEMP */
/* Note that mktemp() requires the initial filename to end in six X's */
#ifndef TEMP_FILE_NAME /* can override from jconfig.h or Makefile */
#define TEMP_FILE_NAME "%sJPG%dXXXXXX"
#endif
LOCAL(void)
select_file_name (char * fname)
{
next_file_num++; /* advance counter */
sprintf(fname, TEMP_FILE_NAME, TEMP_DIRECTORY, next_file_num);
mktemp(fname); /* make sure file name is unique */
/* mktemp replaces the trailing XXXXXX with a unique string of characters */
}
#endif /* NO_MKTEMP */
/*
* Memory allocation and freeing are controlled by the regular library
* routines malloc() and free().
*/
GLOBAL(void *)
jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
{
return (void *) malloc(sizeofobject);
}
GLOBAL(void)
jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
{
free(object);
}
/*
* "Large" objects are treated the same as "small" ones.
* NB: although we include FAR keywords in the routine declarations,
* this file won't actually work in 80x86 small/medium model; at least,
* you probably won't be able to process useful-size images in only 64KB.
*/
GLOBAL(void FAR *)
jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
{
return (void FAR *) malloc(sizeofobject);
}
GLOBAL(void)
jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
{
free(object);
}
/*
* This routine computes the total memory space available for allocation.
* It's impossible to do this in a portable way; our current solution is
* to make the user tell us (with a default value set at compile time).
* If you can actually get the available space, it's a good idea to subtract
* a slop factor of 5% or so.
*/
#ifndef DEFAULT_MAX_MEM /* so can override from makefile */
#define DEFAULT_MAX_MEM 1000000L /* default: one megabyte */
#endif
GLOBAL(long)
jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
long max_bytes_needed, long already_allocated)
{
return cinfo->mem->max_memory_to_use - already_allocated;
}
/*
* Backing store (temporary file) management.
* Backing store objects are only used when the value returned by
* jpeg_mem_available is less than the total space needed. You can dispense
* with these routines if you have plenty of virtual memory; see jmemnobs.c.
*/
METHODDEF(void)
read_backing_store (j_common_ptr cinfo, backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count)
{
if (fseek(info->temp_file, file_offset, SEEK_SET))
ERREXIT(cinfo, JERR_TFILE_SEEK);
if (JFREAD(info->temp_file, buffer_address, byte_count)
!= (size_t) byte_count)
ERREXIT(cinfo, JERR_TFILE_READ);
}
METHODDEF(void)
write_backing_store (j_common_ptr cinfo, backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count)
{
if (fseek(info->temp_file, file_offset, SEEK_SET))
ERREXIT(cinfo, JERR_TFILE_SEEK);
if (JFWRITE(info->temp_file, buffer_address, byte_count)
!= (size_t) byte_count)
ERREXIT(cinfo, JERR_TFILE_WRITE);
}
METHODDEF(void)
close_backing_store (j_common_ptr cinfo, backing_store_ptr info)
{
fclose(info->temp_file); /* close the file */
unlink(info->temp_name); /* delete the file */
/* If your system doesn't have unlink(), use remove() instead.
* remove() is the ANSI-standard name for this function, but if
* your system was ANSI you'd be using jmemansi.c, right?
*/
TRACEMSS(cinfo, 1, JTRC_TFILE_CLOSE, info->temp_name);
}
/*
* Initial opening of a backing-store object.
*/
GLOBAL(void)
jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
long total_bytes_needed)
{
select_file_name(info->temp_name);
if ((info->temp_file = fopen(info->temp_name, RW_BINARY)) == NULL)
ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name);
info->read_backing_store = read_backing_store;
info->write_backing_store = write_backing_store;
info->close_backing_store = close_backing_store;
TRACEMSS(cinfo, 1, JTRC_TFILE_OPEN, info->temp_name);
}
/*
* These routines take care of any system-dependent initialization and
* cleanup required.
*/
GLOBAL(long)
jpeg_mem_init (j_common_ptr cinfo)
{
next_file_num = 0; /* initialize temp file name generator */
return DEFAULT_MAX_MEM; /* default for max_memory_to_use */
}
GLOBAL(void)
jpeg_mem_term (j_common_ptr cinfo)
{
/* no work */
}

View File

@@ -69,9 +69,9 @@ jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
* Here we always say, "we got all you want bud!"
*/
GLOBAL(long)
jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
long max_bytes_needed, long already_allocated)
GLOBAL(size_t)
jpeg_mem_available (j_common_ptr cinfo, size_t min_bytes_needed,
size_t max_bytes_needed, size_t already_allocated)
{
return max_bytes_needed;
}

View File

@@ -1,7 +1,7 @@
/*
* jmemsys.h
*
* Copyright (C) 1992-1996, Thomas G. Lane.
* Copyright (C) 1992-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -14,7 +14,8 @@
* in the IJG distribution. You may need to modify it if you write a
* custom memory manager. If system-dependent changes are needed in
* this file, the best method is to #ifdef them based on a configuration
* symbol supplied in jconfig.h, as we have done with USE_MSDOS_MEMMGR.
* symbol supplied in jconfig.h, as we have done with USE_MSDOS_MEMMGR
* and USE_MAC_MEMMGR.
*/
@@ -99,10 +100,10 @@ EXTERN(void) jpeg_free_large JPP((j_common_ptr cinfo, void FAR * object,
* Conversely, zero may be returned to always use the minimum amount of memory.
*/
EXTERN(long) jpeg_mem_available JPP((j_common_ptr cinfo,
long min_bytes_needed,
long max_bytes_needed,
long already_allocated));
EXTERN(size_t) jpeg_mem_available JPP((j_common_ptr cinfo,
size_t min_bytes_needed,
size_t max_bytes_needed,
size_t already_allocated));
/*
@@ -114,6 +115,7 @@ EXTERN(long) jpeg_mem_available JPP((j_common_ptr cinfo,
#define TEMP_NAME_LENGTH 64 /* max length of a temporary file's name */
#ifdef USE_MSDOS_MEMMGR /* DOS-specific junk */
typedef unsigned short XMSH; /* type of extended-memory handles */
@@ -127,6 +129,11 @@ typedef union {
#endif /* USE_MSDOS_MEMMGR */
#ifdef USE_MAC_MEMMGR /* Mac-specific junk */
#include <Files.h>
#endif /* USE_MAC_MEMMGR */
typedef struct backing_store_struct * backing_store_ptr;
typedef struct backing_store_struct {
@@ -147,13 +154,21 @@ typedef struct backing_store_struct {
/* For the MS-DOS manager (jmemdos.c), we need: */
handle_union handle; /* reference to backing-store storage object */
char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */
#else
#ifdef USE_MAC_MEMMGR
/* For the Mac manager (jmemmac.c), we need: */
short temp_file; /* file reference number to temp file */
FSSpec tempSpec; /* the FSSpec for the temp file */
char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */
#else
/* For a typical implementation with temp files, we need: */
FILE * temp_file; /* stdio reference to temp file */
char temp_name[TEMP_NAME_LENGTH]; /* name of temp file */
#endif
#endif
} backing_store_info;
/*
* Initial opening of a backing-store object. This must fill in the
* read/write/close pointers in the object. The read/write routines

View File

@@ -1,7 +1,8 @@
/*
* jmorecfg.h
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Copyright (C) 1991-1997, Thomas G. Lane.
* Copyright (C) 2009, 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.
*
@@ -62,11 +63,11 @@ typedef unsigned char JSAMPLE;
#else /* not HAVE_UNSIGNED_CHAR */
typedef char JSAMPLE;
#ifdef CHAR_IS_UNSIGNED
#ifdef __CHAR_UNSIGNED__
#define GETJSAMPLE(value) ((int) (value))
#else
#define GETJSAMPLE(value) ((int) (value) & 0xFF)
#endif /* CHAR_IS_UNSIGNED */
#endif /* __CHAR_UNSIGNED__ */
#endif /* HAVE_UNSIGNED_CHAR */
@@ -113,11 +114,11 @@ typedef unsigned char JOCTET;
#else /* not HAVE_UNSIGNED_CHAR */
typedef char JOCTET;
#ifdef CHAR_IS_UNSIGNED
#ifdef __CHAR_UNSIGNED__
#define GETJOCTET(value) (value)
#else
#define GETJOCTET(value) ((value) & 0xFF)
#endif /* CHAR_IS_UNSIGNED */
#endif /* __CHAR_UNSIGNED__ */
#endif /* HAVE_UNSIGNED_CHAR */
@@ -134,11 +135,11 @@ typedef char JOCTET;
#ifdef HAVE_UNSIGNED_CHAR
typedef unsigned char UINT8;
#else /* not HAVE_UNSIGNED_CHAR */
#ifdef CHAR_IS_UNSIGNED
#ifdef __CHAR_UNSIGNED__
typedef char UINT8;
#else /* not CHAR_IS_UNSIGNED */
#else /* not __CHAR_UNSIGNED__ */
typedef short UINT8;
#endif /* CHAR_IS_UNSIGNED */
#endif /* __CHAR_UNSIGNED__ */
#endif /* HAVE_UNSIGNED_CHAR */
/* UINT16 must hold at least the values 0..65535. */
@@ -256,8 +257,6 @@ typedef int boolean;
* (You may HAVE to do that if your compiler doesn't like null source files.)
*/
/* Arithmetic coding is unsupported for legal reasons. Complaints to IBM. */
/* Capability options common to encoder and decoder: */
#define DCT_ISLOW_SUPPORTED /* slow but accurate integer algorithm */
@@ -266,7 +265,6 @@ typedef int boolean;
/* Encoder capability options: */
#undef C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */
#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/
#define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */
@@ -282,9 +280,9 @@ typedef int boolean;
/* Decoder capability options: */
#undef D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */
#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/
#define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */
#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */
#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */
#undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */
@@ -315,31 +313,37 @@ typedef int boolean;
#define RGB_BLUE 2 /* Offset of Blue */
#define RGB_PIXELSIZE 3 /* JSAMPLEs per RGB scanline element */
#define JPEG_NUMCS 12
static const int rgb_red[JPEG_NUMCS] = {
-1, -1, RGB_RED, -1, -1, -1, 0, 0, 2, 2, 3, 1
};
static const int rgb_green[JPEG_NUMCS] = {
-1, -1, RGB_GREEN, -1, -1, -1, 1, 1, 1, 1, 2, 2
};
static const int rgb_blue[JPEG_NUMCS] = {
-1, -1, RGB_BLUE, -1, -1, -1, 2, 2, 0, 0, 1, 3
};
static const int rgb_pixelsize[JPEG_NUMCS] = {
-1, -1, RGB_PIXELSIZE, -1, -1, -1, 3, 4, 3, 4, 4, 4
};
/* Definitions for speed-related optimizations. */
/* If your compiler supports inline functions, define INLINE
* as the inline keyword; otherwise define it as empty.
*/
#ifndef INLINE
#ifdef __GNUC__ /* for instance, GNU C knows about inline */
#define INLINE __inline__
#endif
#ifndef INLINE
#define INLINE /* default is to define it as empty */
#endif
#endif
/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying
* two 16-bit shorts is faster than multiplying two ints. Define MULTIPLIER
* as short on such a machine. MULTIPLIER must be at least 16 bits wide.
*/
#ifndef MULTIPLIER
#ifndef WITH_SIMD
#define MULTIPLIER int /* type for fastest integer multiply */
#else
#define MULTIPLIER short /* prefer 16-bit with SIMD for parellelism */
#endif
#endif

26
jpegcomp.h Normal file
View File

@@ -0,0 +1,26 @@
/*
* jpegcomp.h
*
* Copyright (C) 2010, D. R. Commander
* For conditions of distribution and use, see the accompanying README file.
*
* JPEG compatibility macros
* These declarations are considered internal to the JPEG library; most
* applications using the library shouldn't need to include this file.
*/
#if JPEG_LIB_VERSION >= 70
#define _DCT_scaled_size DCT_h_scaled_size
#define _min_DCT_scaled_size min_DCT_h_scaled_size
#define _min_DCT_h_scaled_size min_DCT_h_scaled_size
#define _min_DCT_v_scaled_size min_DCT_v_scaled_size
#define _jpeg_width jpeg_width
#define _jpeg_height jpeg_height
#else
#define _DCT_scaled_size DCT_scaled_size
#define _min_DCT_scaled_size min_DCT_scaled_size
#define _min_DCT_h_scaled_size min_DCT_scaled_size
#define _min_DCT_v_scaled_size min_DCT_scaled_size
#define _jpeg_width image_width
#define _jpeg_height image_height
#endif

View File

@@ -1,7 +1,8 @@
/*
* jpegint.h
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 1997-2009 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -118,15 +119,16 @@ struct jpeg_entropy_encoder {
/* Marker writing */
struct jpeg_marker_writer {
/* write_any_marker is exported for use by applications */
/* Probably only COM and APPn markers should be written */
JMETHOD(void, write_any_marker, (j_compress_ptr cinfo, int marker,
const JOCTET *dataptr, unsigned int datalen));
JMETHOD(void, write_file_header, (j_compress_ptr cinfo));
JMETHOD(void, write_frame_header, (j_compress_ptr cinfo));
JMETHOD(void, write_scan_header, (j_compress_ptr cinfo));
JMETHOD(void, write_file_trailer, (j_compress_ptr cinfo));
JMETHOD(void, write_tables_only, (j_compress_ptr cinfo));
/* These routines are exported to allow insertion of extra markers */
/* Probably only COM and APPn markers should be written this way */
JMETHOD(void, write_marker_header, (j_compress_ptr cinfo, int marker,
unsigned int datalen));
JMETHOD(void, write_marker_byte, (j_compress_ptr cinfo, int val));
};
@@ -194,9 +196,6 @@ struct jpeg_marker_reader {
JMETHOD(int, read_markers, (j_decompress_ptr cinfo));
/* Read a restart marker --- exported for use by entropy decoder only */
jpeg_marker_parser_method read_restart_marker;
/* Application-overridable marker processing methods */
jpeg_marker_parser_method process_COM;
jpeg_marker_parser_method process_APPn[16];
/* State of marker reader --- nominally internal, but applications
* supplying COM or APPn handlers might like to know the state.
@@ -212,6 +211,10 @@ struct jpeg_entropy_decoder {
JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
JMETHOD(boolean, decode_mcu, (j_decompress_ptr cinfo,
JBLOCKROW *MCU_data));
/* This is here to share code between baseline and progressive decoders; */
/* other modules probably should not use it */
boolean insufficient_data; /* set TRUE after emitting warning */
};
/* Inverse DCT (also performs dequantization) */
@@ -302,6 +305,7 @@ struct jpeg_color_quantizer {
#define jinit_forward_dct jIFDCT
#define jinit_huff_encoder jIHEncoder
#define jinit_phuff_encoder jIPHEncoder
#define jinit_arith_encoder jIAEncoder
#define jinit_marker_writer jIMWriter
#define jinit_master_decompress jIDMaster
#define jinit_d_main_controller jIDMainC
@@ -311,6 +315,7 @@ struct jpeg_color_quantizer {
#define jinit_marker_reader jIMReader
#define jinit_huff_decoder jIHDecoder
#define jinit_phuff_decoder jIPHDecoder
#define jinit_arith_decoder jIADecoder
#define jinit_inverse_dct jIIDCT
#define jinit_upsampler jIUpsampler
#define jinit_color_deconverter jIDColor
@@ -325,6 +330,7 @@ struct jpeg_color_quantizer {
#define jzero_far jZeroFar
#define jpeg_zigzag_order jZIGTable
#define jpeg_natural_order jZAGTable
#define jpeg_aritab jAriTab
#endif /* NEED_SHORT_EXTERNAL_NAMES */
@@ -343,6 +349,7 @@ EXTERN(void) jinit_downsampler JPP((j_compress_ptr cinfo));
EXTERN(void) jinit_forward_dct JPP((j_compress_ptr cinfo));
EXTERN(void) jinit_huff_encoder JPP((j_compress_ptr cinfo));
EXTERN(void) jinit_phuff_encoder JPP((j_compress_ptr cinfo));
EXTERN(void) jinit_arith_encoder JPP((j_compress_ptr cinfo));
EXTERN(void) jinit_marker_writer JPP((j_compress_ptr cinfo));
/* Decompression module initialization routines */
EXTERN(void) jinit_master_decompress JPP((j_decompress_ptr cinfo));
@@ -356,6 +363,7 @@ EXTERN(void) jinit_input_controller JPP((j_decompress_ptr cinfo));
EXTERN(void) jinit_marker_reader JPP((j_decompress_ptr cinfo));
EXTERN(void) jinit_huff_decoder JPP((j_decompress_ptr cinfo));
EXTERN(void) jinit_phuff_decoder JPP((j_decompress_ptr cinfo));
EXTERN(void) jinit_arith_decoder JPP((j_decompress_ptr cinfo));
EXTERN(void) jinit_inverse_dct JPP((j_decompress_ptr cinfo));
EXTERN(void) jinit_upsampler JPP((j_decompress_ptr cinfo));
EXTERN(void) jinit_color_deconverter JPP((j_decompress_ptr cinfo));
@@ -367,7 +375,7 @@ EXTERN(void) jinit_memory_mgr JPP((j_common_ptr cinfo));
/* Utility routines in jutils.c */
EXTERN(long) jdiv_round_up JPP((long a, long b));
EXTERN(long) jround_up JPP((long a, long b));
EXTERN(size_t) jround_up JPP((size_t a, size_t b));
EXTERN(void) jcopy_sample_rows JPP((JSAMPARRAY input_array, int source_row,
JSAMPARRAY output_array, int dest_row,
int num_rows, JDIMENSION num_cols));
@@ -375,9 +383,14 @@ EXTERN(void) jcopy_block_row JPP((JBLOCKROW input_row, JBLOCKROW output_row,
JDIMENSION num_blocks));
EXTERN(void) jzero_far JPP((void FAR * target, size_t bytestozero));
/* Constant tables in jutils.c */
#if 0 /* This table is not actually needed in v6a */
extern const int jpeg_zigzag_order[]; /* natural coef order to zigzag order */
#endif
extern const int jpeg_natural_order[]; /* zigzag coef order to natural order */
/* Arithmetic coding probability estimation tables in jaricom.c */
extern const INT32 jpeg_aritab[];
/* Suppress undefined-structure complaints if necessary. */
#ifdef INCOMPLETE_TYPES_BROKEN

184
jpeglib.h
View File

@@ -1,7 +1,9 @@
/*
* jpeglib.h
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Copyright (C) 1991-1998, Thomas G. Lane.
* Modified 2002-2009 by Guido Vollbeding.
* Copyright (C) 2009-2010, 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.
*
@@ -26,11 +28,11 @@
#include "jmorecfg.h" /* seldom changed options */
/* Version ID for the JPEG library.
* Might be useful for tests like "#if JPEG_LIB_VERSION >= 60".
*/
#define JPEG_LIB_VERSION 61 /* Version 6a */
#ifdef __cplusplus
#ifndef DONT_USE_EXTERN_C
extern "C" {
#endif
#endif
/* Various constants determining the sizes of things.
@@ -144,12 +146,17 @@ typedef struct {
* Values of 1,2,4,8 are likely to be supported. Note that different
* components may receive different IDCT scalings.
*/
#if JPEG_LIB_VERSION >= 70
int DCT_h_scaled_size;
int DCT_v_scaled_size;
#else
int DCT_scaled_size;
#endif
/* The downsampled dimensions are the component's actual, unpadded number
* of samples at the main buffer (preprocessing/compression interface), thus
* downsampled_width = ceil(image_width * Hi/Hmax)
* and similarly for height. For decompression, IDCT scaling is included, so
* downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE)
* downsampled_width = ceil(image_width * Hi/Hmax * DCT_[h_]scaled_size/DCTSIZE)
*/
JDIMENSION downsampled_width; /* actual width in samples */
JDIMENSION downsampled_height; /* actual height in samples */
@@ -164,7 +171,7 @@ typedef struct {
int MCU_width; /* number of blocks per MCU, horizontally */
int MCU_height; /* number of blocks per MCU, vertically */
int MCU_blocks; /* MCU_width * MCU_height */
int MCU_sample_width; /* MCU width in samples, MCU_width*DCT_scaled_size */
int MCU_sample_width; /* MCU width in samples, MCU_width*DCT_[h_]scaled_size */
int last_col_width; /* # of non-dummy blocks across in last MCU */
int last_row_height; /* # of non-dummy blocks down in last MCU */
@@ -188,16 +195,37 @@ typedef struct {
int Ah, Al; /* progressive JPEG successive approx. parms */
} jpeg_scan_info;
/* The decompressor can save APPn and COM markers in a list of these: */
typedef struct jpeg_marker_struct FAR * jpeg_saved_marker_ptr;
struct jpeg_marker_struct {
jpeg_saved_marker_ptr next; /* next in list, or NULL */
UINT8 marker; /* marker code: JPEG_COM, or JPEG_APP0+n */
unsigned int original_length; /* # bytes of data in the file */
unsigned int data_length; /* # bytes of data saved at data[] */
JOCTET FAR * data; /* the data contained in the marker */
/* the marker length word is not counted in data_length or original_length */
};
/* Known color spaces. */
#define JCS_EXTENSIONS 1
typedef enum {
JCS_UNKNOWN, /* error/unspecified */
JCS_GRAYSCALE, /* monochrome */
JCS_RGB, /* red/green/blue */
JCS_RGB, /* red/green/blue as specified by the RGB_RED, RGB_GREEN,
RGB_BLUE, and RGB_PIXELSIZE macros */
JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */
JCS_CMYK, /* C/M/Y/K */
JCS_YCCK /* Y/Cb/Cr/K */
JCS_YCCK, /* Y/Cb/Cr/K */
JCS_EXT_RGB, /* red/green/blue */
JCS_EXT_RGBX, /* red/green/blue/x */
JCS_EXT_BGR, /* blue/green/red */
JCS_EXT_BGRX, /* blue/green/red/x */
JCS_EXT_XBGR, /* x/blue/green/red */
JCS_EXT_XRGB /* x/red/green/blue */
} J_COLOR_SPACE;
/* DCT/IDCT algorithm options. */
@@ -230,8 +258,9 @@ typedef enum {
struct jpeg_error_mgr * err; /* Error handler module */\
struct jpeg_memory_mgr * mem; /* Memory manager module */\
struct jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\
boolean is_decompressor; /* so common code can tell which is which */\
int global_state /* for checking call sequence validity */
void * client_data; /* Available for use by application */\
boolean is_decompressor; /* So common code can tell which is which */\
int global_state /* For checking call sequence validity */
/* Routines that are to be used by both halves of the library are declared
* to receive a pointer to this structure. There are no actual instances of
@@ -278,6 +307,19 @@ struct jpeg_compress_struct {
* helper routines to simplify changing parameters.
*/
#if JPEG_LIB_VERSION >= 70
unsigned int scale_num, scale_denom; /* fraction by which to scale image */
JDIMENSION jpeg_width; /* scaled JPEG image width */
JDIMENSION jpeg_height; /* scaled JPEG image height */
/* Dimensions of actual JPEG image that will be written to file,
* derived from input dimensions by scaling factors above.
* These fields are computed by jpeg_start_compress().
* You can also use jpeg_calc_jpeg_dimensions() to determine these values
* in advance of calling jpeg_start_compress().
*/
#endif
int data_precision; /* bits of precision in image data */
int num_components; /* # of color components in JPEG image */
@@ -285,14 +327,19 @@ struct jpeg_compress_struct {
jpeg_component_info * comp_info;
/* comp_info[i] describes component that appears i'th in SOF */
JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS];
/* ptrs to coefficient quantization tables, or NULL if not defined */
#if JPEG_LIB_VERSION >= 70
int q_scale_factor[NUM_QUANT_TBLS];
#endif
/* ptrs to coefficient quantization tables, or NULL if not defined,
* and corresponding scale factors (percentage, initialized 100).
*/
JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS];
JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS];
/* ptrs to Huffman coding tables, or NULL if not defined */
UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */
UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */
UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */
@@ -308,6 +355,9 @@ struct jpeg_compress_struct {
boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */
boolean optimize_coding; /* TRUE=optimize entropy encoding parms */
boolean CCIR601_sampling; /* TRUE=first samples are cosited */
#if JPEG_LIB_VERSION >= 70
boolean do_fancy_downsampling; /* TRUE=apply fancy downsampling */
#endif
int smoothing_factor; /* 1..100, or 0 for no input smoothing */
J_DCT_METHOD dct_method; /* DCT algorithm selector */
@@ -322,6 +372,8 @@ struct jpeg_compress_struct {
/* Parameters controlling emission of special markers. */
boolean write_JFIF_header; /* should a JFIF marker be written? */
UINT8 JFIF_major_version; /* What to write for the JFIF version number */
UINT8 JFIF_minor_version;
/* These three values are not used by the JPEG code, merely copied */
/* into the JFIF APP0 marker. density_unit can be 0 for unknown, */
/* 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect */
@@ -349,6 +401,11 @@ struct jpeg_compress_struct {
int max_h_samp_factor; /* largest h_samp_factor */
int max_v_samp_factor; /* largest v_samp_factor */
#if JPEG_LIB_VERSION >= 70
int min_DCT_h_scaled_size; /* smallest DCT_h_scaled_size of any component */
int min_DCT_v_scaled_size; /* smallest DCT_v_scaled_size of any component */
#endif
JDIMENSION total_iMCU_rows; /* # of iMCU rows to be input to coef ctlr */
/* The coefficient controller receives data in units of MCU rows as defined
* for fully interleaved scans (whether the JPEG file is interleaved or not).
@@ -374,6 +431,12 @@ struct jpeg_compress_struct {
int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */
#if JPEG_LIB_VERSION >= 80
int block_size; /* the basic DCT block size: 1..16 */
const int * natural_order; /* natural-order position array */
int lim_Se; /* min( Se, DCTSIZE2-1 ) */
#endif
/*
* Links to compression subobjects (methods and private variables of modules)
*/
@@ -386,6 +449,8 @@ struct jpeg_compress_struct {
struct jpeg_downsampler * downsample;
struct jpeg_forward_dct * fdct;
struct jpeg_entropy_encoder * entropy;
jpeg_scan_info * script_space; /* workspace for jpeg_simple_progression */
int script_space_size;
};
@@ -518,6 +583,9 @@ struct jpeg_decompress_struct {
jpeg_component_info * comp_info;
/* comp_info[i] describes component that appears i'th in SOF */
#if JPEG_LIB_VERSION >= 80
boolean is_baseline; /* TRUE if Baseline SOF0 encountered */
#endif
boolean progressive_mode; /* TRUE if SOFn specifies progressive mode */
boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */
@@ -531,7 +599,9 @@ struct jpeg_decompress_struct {
* the JPEG library.
*/
boolean saw_JFIF_marker; /* TRUE iff a JFIF APP0 marker was found */
/* Data copied from JFIF marker: */
/* Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: */
UINT8 JFIF_major_version; /* JFIF version number */
UINT8 JFIF_minor_version;
UINT8 density_unit; /* JFIF code for pixel size units */
UINT16 X_density; /* Horizontal pixel density */
UINT16 Y_density; /* Vertical pixel density */
@@ -540,6 +610,12 @@ struct jpeg_decompress_struct {
boolean CCIR601_sampling; /* TRUE=first samples are cosited */
/* Aside from the specific data retained from APPn markers known to the
* library, the uninterpreted contents of any or all APPn and COM markers
* can be saved in a list for examination by the application.
*/
jpeg_saved_marker_ptr marker_list; /* Head of list of saved markers */
/* Remaining fields are known throughout decompressor, but generally
* should not be touched by a surrounding application.
*/
@@ -550,7 +626,12 @@ struct jpeg_decompress_struct {
int max_h_samp_factor; /* largest h_samp_factor */
int max_v_samp_factor; /* largest v_samp_factor */
#if JPEG_LIB_VERSION >= 70
int min_DCT_h_scaled_size; /* smallest DCT_h_scaled_size of any component */
int min_DCT_v_scaled_size; /* smallest DCT_v_scaled_size of any component */
#else
int min_DCT_scaled_size; /* smallest DCT_scaled_size of any component */
#endif
JDIMENSION total_iMCU_rows; /* # of iMCU rows in image */
/* The coefficient controller's input and output progress is measured in
@@ -558,7 +639,7 @@ struct jpeg_decompress_struct {
* in fully interleaved JPEG scans, but are used whether the scan is
* interleaved or not. We define an iMCU row as v_samp_factor DCT block
* rows of each component. Therefore, the IDCT output contains
* v_samp_factor*DCT_scaled_size sample rows of a component per iMCU row.
* v_samp_factor*DCT_[v_]scaled_size sample rows of a component per iMCU row.
*/
JSAMPLE * sample_range_limit; /* table for fast range-limiting */
@@ -582,6 +663,14 @@ struct jpeg_decompress_struct {
int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */
#if JPEG_LIB_VERSION >= 80
/* These fields are derived from Se of first SOS marker.
*/
int block_size; /* the basic DCT block size: 1..16 */
const int * natural_order; /* natural-order position array for entropy decode */
int lim_Se; /* min( Se, DCTSIZE2-1 ) for entropy decode */
#endif
/* This field is shared between entropy decoder and marker parser.
* It is either zero or the code of a JPEG marker that has been
* read from the data source, but has not yet been processed.
@@ -772,6 +861,9 @@ struct jpeg_memory_mgr {
* after creating the JPEG object.
*/
long max_memory_to_use;
/* Maximum allocation request accepted by alloc_large. */
long max_alloc_chunk;
};
@@ -808,11 +900,18 @@ typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo));
#define jpeg_destroy_decompress jDestDecompress
#define jpeg_stdio_dest jStdDest
#define jpeg_stdio_src jStdSrc
#if JPEG_LIB_VERSION >= 80
#define jpeg_mem_dest jMemDest
#define jpeg_mem_src jMemSrc
#endif
#define jpeg_set_defaults jSetDefaults
#define jpeg_set_colorspace jSetColorspace
#define jpeg_default_colorspace jDefColorspace
#define jpeg_set_quality jSetQuality
#define jpeg_set_linear_quality jSetLQuality
#if JPEG_LIB_VERSION >= 70
#define jpeg_default_qtables jDefQTables
#endif
#define jpeg_add_quant_table jAddQuantTable
#define jpeg_quality_scaling jQualityScaling
#define jpeg_simple_progression jSimProgress
@@ -822,8 +921,13 @@ typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo));
#define jpeg_start_compress jStrtCompress
#define jpeg_write_scanlines jWrtScanlines
#define jpeg_finish_compress jFinCompress
#if JPEG_LIB_VERSION >= 70
#define jpeg_calc_jpeg_dimensions jCjpegDimensions
#endif
#define jpeg_write_raw_data jWrtRawData
#define jpeg_write_marker jWrtMarker
#define jpeg_write_m_header jWrtMHeader
#define jpeg_write_m_byte jWrtMByte
#define jpeg_write_tables jWrtTables
#define jpeg_read_header jReadHeader
#define jpeg_start_decompress jStrtDecompress
@@ -836,7 +940,11 @@ typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo));
#define jpeg_input_complete jInComplete
#define jpeg_new_colormap jNewCMap
#define jpeg_consume_input jConsumeInput
#if JPEG_LIB_VERSION >= 80
#define jpeg_core_output_dimensions jCoreDimensions
#endif
#define jpeg_calc_output_dimensions jCalcDimensions
#define jpeg_save_markers jSaveMarkers
#define jpeg_set_marker_processor jSetMarker
#define jpeg_read_coefficients jReadCoefs
#define jpeg_write_coefficients jWrtCoefs
@@ -879,6 +987,16 @@ EXTERN(void) jpeg_destroy_decompress JPP((j_decompress_ptr cinfo));
EXTERN(void) jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile));
EXTERN(void) jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile));
#if JPEG_LIB_VERSION >= 80
/* Data source and destination managers: memory buffers. */
EXTERN(void) jpeg_mem_dest JPP((j_compress_ptr cinfo,
unsigned char ** outbuffer,
unsigned long * outsize));
EXTERN(void) jpeg_mem_src JPP((j_decompress_ptr cinfo,
unsigned char * inbuffer,
unsigned long insize));
#endif
/* Default parameter setup for compression */
EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo));
/* Compression parameter setup aids */
@@ -890,6 +1008,10 @@ EXTERN(void) jpeg_set_quality JPP((j_compress_ptr cinfo, int quality,
EXTERN(void) jpeg_set_linear_quality JPP((j_compress_ptr cinfo,
int scale_factor,
boolean force_baseline));
#if JPEG_LIB_VERSION >= 70
EXTERN(void) jpeg_default_qtables JPP((j_compress_ptr cinfo,
boolean force_baseline));
#endif
EXTERN(void) jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl,
const unsigned int *basic_table,
int scale_factor,
@@ -909,15 +1031,25 @@ EXTERN(JDIMENSION) jpeg_write_scanlines JPP((j_compress_ptr cinfo,
JDIMENSION num_lines));
EXTERN(void) jpeg_finish_compress JPP((j_compress_ptr cinfo));
#if JPEG_LIB_VERSION >= 70
/* Precalculate JPEG dimensions for current compression parameters. */
EXTERN(void) jpeg_calc_jpeg_dimensions JPP((j_compress_ptr cinfo));
#endif
/* Replaces jpeg_write_scanlines when writing raw downsampled data. */
EXTERN(JDIMENSION) jpeg_write_raw_data JPP((j_compress_ptr cinfo,
JSAMPIMAGE data,
JDIMENSION num_lines));
/* Write a special marker. See libjpeg.doc concerning safe usage. */
/* Write a special marker. See libjpeg.txt concerning safe usage. */
EXTERN(void) jpeg_write_marker
JPP((j_compress_ptr cinfo, int marker,
const JOCTET * dataptr, unsigned int datalen));
/* Same, but piecemeal. */
EXTERN(void) jpeg_write_m_header
JPP((j_compress_ptr cinfo, int marker, unsigned int datalen));
EXTERN(void) jpeg_write_m_byte
JPP((j_compress_ptr cinfo, int val));
/* Alternate compression function: just write an abbreviated table file */
EXTERN(void) jpeg_write_tables JPP((j_compress_ptr cinfo));
@@ -963,8 +1095,16 @@ EXTERN(int) jpeg_consume_input JPP((j_decompress_ptr cinfo));
#define JPEG_SCAN_COMPLETED 4 /* Completed last iMCU row of a scan */
/* Precalculate output dimensions for current decompression parameters. */
#if JPEG_LIB_VERSION >= 80
EXTERN(void) jpeg_core_output_dimensions JPP((j_decompress_ptr cinfo));
#endif
EXTERN(void) jpeg_calc_output_dimensions JPP((j_decompress_ptr cinfo));
/* Control saving of COM and APPn markers into marker_list. */
EXTERN(void) jpeg_save_markers
JPP((j_decompress_ptr cinfo, int marker_code,
unsigned int length_limit));
/* Install a special processing method for COM or APPn markers. */
EXTERN(void) jpeg_set_marker_processor
JPP((j_decompress_ptr cinfo, int marker_code,
@@ -1052,4 +1192,10 @@ struct jpeg_color_quantizer { long dummy; };
#include "jerror.h" /* fetch error codes too */
#endif
#ifdef __cplusplus
#ifndef DONT_USE_EXTERN_C
}
#endif
#endif
#endif /* JPEGLIB_H */

View File

@@ -1,6 +1,6 @@
.TH JPEGTRAN 1 "15 June 1995"
.TH JPEGTRAN 1 "11 October 2010"
.SH NAME
jpegtran \- lossless transcoding of JPEG files
jpegtran \- lossless transformation of JPEG files
.SH SYNOPSIS
.B jpegtran
[
@@ -13,23 +13,27 @@ jpegtran \- lossless transcoding of JPEG files
.SH DESCRIPTION
.LP
.B jpegtran
translates JPEG files from one variant of JPEG to another, for example
from baseline JPEG to progressive JPEG. The transformation is lossless:
no image degradation occurs, which would not be true if you used
performs various useful transformations of JPEG files.
It can translate the coded representation from one variant of JPEG to another,
for example from baseline JPEG to progressive JPEG or vice versa. It can also
perform some rearrangements of the image data, for example turning an image
from landscape to portrait format by rotation.
.PP
.B jpegtran
works by rearranging the compressed data (DCT coefficients), without
ever fully decoding the image. Therefore, its transformations are lossless:
there is no image degradation at all, which would not be true if you used
.B djpeg
followed by
.BR cjpeg .
However, you cannot alter the image quality, because that would not be
a lossless operation.
.B cjpeg
to accomplish the same conversion. But by the same token,
.B jpegtran
cannot perform lossy operations such as changing the image quality.
.PP
.B jpegtran
reads the named JPEG/JFIF file, or the standard input if no file is
named, and produces a JPEG/JFIF file on the standard output.
.SH OPTIONS
.B jpegtran
accepts a subset of the switches recognized by
.BR cjpeg .
If you specify no switches, you get a plain baseline JPEG output file.
.PP
All switch names may be abbreviated; for example,
.B \-optimize
may be written
@@ -41,41 +45,156 @@ British spellings are also accepted (e.g.,
.BR \-optimise ),
though for brevity these are not mentioned below.
.PP
The basic switches are:
To specify the coded JPEG representation used in the output file,
.B jpegtran
accepts a subset of the switches recognized by
.BR cjpeg :
.TP
.B \-optimize
Perform optimization of entropy encoding parameters. Without this, default
encoding parameters are used.
.B \-optimize
usually makes the JPEG file a little smaller, but at the price of slower
compression. Note that
.B \-progressive
implies
.BR \-optimize .
Perform optimization of entropy encoding parameters.
.TP
.B \-progressive
Create progressive JPEG file (see below).
.PP
The
.B \-progressive
switch creates a "progressive JPEG" file. In this type of JPEG file, the data
is stored in multiple scans of increasing quality. If the file is being
transmitted over a slow communications link, the decoder can use the first
scan to display a low-quality image very quickly, and can then improve the
display with each subsequent scan. The final image is exactly equivalent to a
standard JPEG file of the same quality setting, and the total file size is
about the same --- often a little smaller.
.B Caution:
progressive JPEG is not yet widely implemented, so many decoders will be
unable to view a progressive JPEG file at all.
.PP
Switches for advanced users:
Create progressive JPEG file.
.TP
.BI \-restart " N"
Emit a JPEG restart marker every N MCU rows, or every N MCU blocks if "B" is
attached to the number.
.B \-restart 0
(the default) means no restart markers.
.TP
.B \-arithmetic
Use arithmetic coding.
.TP
.BI \-scans " file"
Use the scan script given in the specified text file.
.PP
See
.BR cjpeg (1)
for more details about these switches.
If you specify none of these switches, you get a plain baseline-JPEG output
file. The quality setting and so forth are determined by the input file.
.PP
The image can be losslessly transformed by giving one of these switches:
.TP
.B \-flip horizontal
Mirror image horizontally (left-right).
.TP
.B \-flip vertical
Mirror image vertically (top-bottom).
.TP
.B \-rotate 90
Rotate image 90 degrees clockwise.
.TP
.B \-rotate 180
Rotate image 180 degrees.
.TP
.B \-rotate 270
Rotate image 270 degrees clockwise (or 90 ccw).
.TP
.B \-transpose
Transpose image (across UL-to-LR axis).
.TP
.B \-transverse
Transverse transpose (across UR-to-LL axis).
.PP
The transpose transformation has no restrictions regarding image dimensions.
The other transformations operate rather oddly if the image dimensions are not
a multiple of the iMCU size (usually 8 or 16 pixels), because they can only
transform complete blocks of DCT coefficient data in the desired way.
.PP
.BR jpegtran 's
default behavior when transforming an odd-size image is designed
to preserve exact reversibility and mathematical consistency of the
transformation set. As stated, transpose is able to flip the entire image
area. Horizontal mirroring leaves any partial iMCU column at the right edge
untouched, but is able to flip all rows of the image. Similarly, vertical
mirroring leaves any partial iMCU row at the bottom edge untouched, but is
able to flip all columns. The other transforms can be built up as sequences
of transpose and flip operations; for consistency, their actions on edge
pixels are defined to be the same as the end result of the corresponding
transpose-and-flip sequence.
.PP
For practical use, you may prefer to discard any untransformable edge pixels
rather than having a strange-looking strip along the right and/or bottom edges
of a transformed image. To do this, add the
.B \-trim
switch:
.TP
.B \-trim
Drop non-transformable edge blocks.
.IP
Obviously, a transformation with
.B \-trim
is not reversible, so strictly speaking
.B jpegtran
with this switch is not lossless. Also, the expected mathematical
equivalences between the transformations no longer hold. For example,
.B \-rot 270 -trim
trims only the bottom edge, but
.B \-rot 90 -trim
followed by
.B \-rot 180 -trim
trims both edges.
.TP
.B \-perfect
If you are only interested in perfect transformations, add the
.B \-perfect
switch. This causes
.B jpegtran
to fail with an error if the transformation is not perfect.
.IP
For example, you may want to do
.IP
.B (jpegtran \-rot 90 -perfect
.I foo.jpg
.B || djpeg
.I foo.jpg
.B | pnmflip \-r90 | cjpeg)
.IP
to do a perfect rotation, if available, or an approximated one if not.
.TP
.B \-crop WxH+X+Y
Crop the image to a rectangular region of width W and height H, starting at
point X,Y. The lossless crop feature discards data outside of a given image
region but losslessly preserves what is inside. Like the rotate and flip
transforms, lossless crop is restricted by the current JPEG format; the upper
left corner of the selected region must fall on an iMCU boundary. If it
doesn't, then it is silently moved up and/or left to the nearest iMCU boundary
(the lower right corner is unchanged.)
.PP
Other not-strictly-lossless transformation switches are:
.TP
.B \-grayscale
Force grayscale output.
.IP
This option discards the chrominance channels if the input image is YCbCr
(ie, a standard color JPEG), resulting in a grayscale JPEG file. The
luminance channel is preserved exactly, so this is a better method of reducing
to grayscale than decompression, conversion, and recompression. This switch
is particularly handy for fixing a monochrome picture that was mistakenly
encoded as a color JPEG. (In such a case, the space savings from getting rid
of the near-empty chroma channels won't be large; but the decoding time for
a grayscale JPEG is substantially less than that for a color JPEG.)
.PP
.B jpegtran
also recognizes these switches that control what to do with "extra" markers,
such as comment blocks:
.TP
.B \-copy none
Copy no extra markers from source file. This setting suppresses all
comments and other excess baggage present in the source file.
.TP
.B \-copy comments
Copy only comment markers. This setting copies comments from the source file
but discards any other data which is inessential for image display.
.TP
.B \-copy all
Copy all extra markers. This setting preserves miscellaneous markers
found in the source file, such as JFIF thumbnails, Exif data, and Photoshop
settings. In some files, these extra markers can be sizable.
.PP
The default behavior is \fB-copy comments\fR. (Note: in IJG releases v6 and
v6a, \fBjpegtran\fR always did the equivalent of \fB-copy none\fR.)
.PP
Additional switches recognized by jpegtran are:
.TP
.BI \-maxmemory " N"
Set limit for amount of memory to use in processing large images. Value is
@@ -95,26 +214,6 @@ give more output. Also, version information is printed at startup.
.B \-debug
Same as
.BR \-verbose .
.PP
The
.B \-restart
option inserts extra markers that allow a JPEG decoder to resynchronize after
a transmission error. Without restart markers, any damage to a compressed
file will usually ruin the image from the point of the error to the end of the
image; with restart markers, the damage is usually confined to the portion of
the image up to the next restart marker. Of course, the restart markers
occupy extra space. We recommend
.B \-restart 1
for images that will be transmitted across unreliable networks such as Usenet.
.PP
Switches for wizards:
.TP
.BI \-scans " file"
Use the scan script given in the specified text file.
.PP
The "wizard" switches are intended for experimentation with JPEG. If you
don't know what you are doing, \fBdon't use them\fR. These switches are
documented further in the file wizard.doc.
.SH EXAMPLES
.LP
This example converts a baseline JPEG file to progressive form:
@@ -123,6 +222,14 @@ This example converts a baseline JPEG file to progressive form:
.I foo.jpg
.B >
.I fooprog.jpg
.PP
This example rotates an image 90 degrees clockwise, discarding any
unrotatable edge pixels:
.IP
.B jpegtran \-rot 90 -trim
.I foo.jpg
.B >
.I foo90.jpg
.SH ENVIRONMENT
.TP
.B JPEGMEM
@@ -145,6 +252,12 @@ Communications of the ACM, April 1991 (vol. 34, no. 4), pp. 30-44.
.SH AUTHOR
Independent JPEG Group
.SH BUGS
Arithmetic coding is not supported for legal reasons.
The transform options can't transform odd-size images perfectly. Use
.B \-trim
or
.B \-perfect
if you don't like the results.
.PP
Still not as fast as we'd like.
The entire image is read into memory and then written out again, even in
cases where this isn't really necessary. Expect swapping on large images,
especially when using the more complex transform options.

View File

@@ -1,17 +1,21 @@
/*
* jpegtran.c
*
* Copyright (C) 1995-1996, Thomas G. Lane.
* Copyright (C) 1995-2010, Thomas G. Lane, Guido Vollbeding.
* Copyright (C) 2010, 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.
*
* This file contains a command-line user interface for JPEG transcoding.
* It is very similar to cjpeg.c, but provides lossless transcoding between
* different JPEG file formats.
* It is very similar to cjpeg.c, and partly to djpeg.c, but provides
* lossless transcoding between different JPEG file formats. It also
* provides some lossless and sort-of-lossless transformations of JPEG data.
*/
#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
#include "transupp.h" /* Support routines for jpegtran */
#include "jversion.h" /* for version message */
#include "config.h"
#ifdef USE_CCOMMAND /* command-line reader for Macintosh */
#ifdef __MWERKS__
@@ -35,6 +39,8 @@
static const char * progname; /* program name for error messages */
static char * outfilename; /* for -outfile switch */
static JCOPY_OPTION copyoption; /* -copy switch */
static jpeg_transform_info transformoption; /* image transformation options */
LOCAL(void)
@@ -49,11 +55,27 @@ usage (void)
#endif
fprintf(stderr, "Switches (names may be abbreviated):\n");
fprintf(stderr, " -copy none Copy no extra markers from source file\n");
fprintf(stderr, " -copy comments Copy only comment markers (default)\n");
fprintf(stderr, " -copy all Copy all extra markers\n");
#ifdef ENTROPY_OPT_SUPPORTED
fprintf(stderr, " -optimize Optimize Huffman table (smaller file, but slow compression)\n");
#endif
#ifdef C_PROGRESSIVE_SUPPORTED
fprintf(stderr, " -progressive Create progressive JPEG file\n");
#endif
fprintf(stderr, "Switches for modifying the image:\n");
#if TRANSFORMS_SUPPORTED
fprintf(stderr, " -crop WxH+X+Y Crop to a rectangular subarea\n");
fprintf(stderr, " -grayscale Reduce to grayscale (omit color data)\n");
fprintf(stderr, " -flip [horizontal|vertical] Mirror image (left-right or top-bottom)\n");
fprintf(stderr, " -perfect Fail if there is non-transformable edge blocks\n");
fprintf(stderr, " -rotate [90|180|270] Rotate image (degrees clockwise)\n");
#endif
#if TRANSFORMS_SUPPORTED
fprintf(stderr, " -transpose Transpose image\n");
fprintf(stderr, " -transverse Transverse transpose image\n");
fprintf(stderr, " -trim Drop non-transformable edge blocks\n");
#endif
fprintf(stderr, "Switches for advanced users:\n");
fprintf(stderr, " -restart N Set restart interval in rows, or in blocks with B\n");
@@ -71,6 +93,29 @@ usage (void)
}
LOCAL(void)
select_transform (JXFORM_CODE transform)
/* Silly little routine to detect multiple transform options,
* which we can't handle.
*/
{
#if TRANSFORMS_SUPPORTED
if (transformoption.transform == JXFORM_NONE ||
transformoption.transform == transform) {
transformoption.transform = transform;
} else {
fprintf(stderr, "%s: can only do one image transformation at a time\n",
progname);
usage();
}
#else
fprintf(stderr, "%s: sorry, image transformation was not compiled\n",
progname);
exit(EXIT_FAILURE);
#endif
}
LOCAL(int)
parse_switches (j_compress_ptr cinfo, int argc, char **argv,
int last_file_arg_seen, boolean for_real)
@@ -91,6 +136,12 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
/* Set up default JPEG parameters. */
simple_progressive = FALSE;
outfilename = NULL;
copyoption = JCOPYOPT_DEFAULT;
transformoption.transform = JXFORM_NONE;
transformoption.perfect = FALSE;
transformoption.trim = FALSE;
transformoption.force_grayscale = FALSE;
transformoption.crop = FALSE;
cinfo->err->trace_level = 0;
/* Scan command line options, adjust parameters */
@@ -117,18 +168,67 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
exit(EXIT_FAILURE);
#endif
} else if (keymatch(arg, "copy", 2)) {
/* Select which extra markers to copy. */
if (++argn >= argc) /* advance to next argument */
usage();
if (keymatch(argv[argn], "none", 1)) {
copyoption = JCOPYOPT_NONE;
} else if (keymatch(argv[argn], "comments", 1)) {
copyoption = JCOPYOPT_COMMENTS;
} else if (keymatch(argv[argn], "all", 1)) {
copyoption = JCOPYOPT_ALL;
} else
usage();
} else if (keymatch(arg, "crop", 2)) {
/* Perform lossless cropping. */
#if TRANSFORMS_SUPPORTED
if (++argn >= argc) /* advance to next argument */
usage();
if (! jtransform_parse_crop_spec(&transformoption, argv[argn])) {
fprintf(stderr, "%s: bogus -crop argument '%s'\n",
progname, argv[argn]);
exit(EXIT_FAILURE);
}
#else
select_transform(JXFORM_NONE); /* force an error */
#endif
} else if (keymatch(arg, "debug", 1) || keymatch(arg, "verbose", 1)) {
/* Enable debug printouts. */
/* On first -d, print version identification */
static boolean printed_version = FALSE;
if (! printed_version) {
fprintf(stderr, "Independent JPEG Group's JPEGTRAN, version %s\n%s\n",
fprintf(stderr, "%s version %s (build %s)\n",
PACKAGE_NAME, VERSION, BUILD);
fprintf(stderr, "%s\n\n", LJTCOPYRIGHT);
fprintf(stderr, "Based on Independent JPEG Group's libjpeg, version %s\n%s\n\n",
JVERSION, JCOPYRIGHT);
printed_version = TRUE;
}
cinfo->err->trace_level++;
} else if (keymatch(arg, "flip", 1)) {
/* Mirror left-right or top-bottom. */
if (++argn >= argc) /* advance to next argument */
usage();
if (keymatch(argv[argn], "horizontal", 1))
select_transform(JXFORM_FLIP_H);
else if (keymatch(argv[argn], "vertical", 1))
select_transform(JXFORM_FLIP_V);
else
usage();
} else if (keymatch(arg, "grayscale", 1) || keymatch(arg, "greyscale",1)) {
/* Force to grayscale. */
#if TRANSFORMS_SUPPORTED
transformoption.force_grayscale = TRUE;
#else
select_transform(JXFORM_NONE); /* force an error */
#endif
} else if (keymatch(arg, "maxmemory", 3)) {
/* Maximum memory in Kb (or Mb with 'm'). */
long lval;
@@ -158,7 +258,12 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
usage();
outfilename = argv[argn]; /* save it away for later use */
} else if (keymatch(arg, "progressive", 1)) {
} else if (keymatch(arg, "perfect", 2)) {
/* Fail if there is any partial edge MCUs that the transform can't
* handle. */
transformoption.perfect = TRUE;
} else if (keymatch(arg, "progressive", 2)) {
/* Select simple progressive mode. */
#ifdef C_PROGRESSIVE_SUPPORTED
simple_progressive = TRUE;
@@ -188,7 +293,20 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
/* restart_interval will be computed during startup */
}
} else if (keymatch(arg, "scans", 2)) {
} else if (keymatch(arg, "rotate", 2)) {
/* Rotate 90, 180, or 270 degrees (measured clockwise). */
if (++argn >= argc) /* advance to next argument */
usage();
if (keymatch(argv[argn], "90", 2))
select_transform(JXFORM_ROT_90);
else if (keymatch(argv[argn], "180", 3))
select_transform(JXFORM_ROT_180);
else if (keymatch(argv[argn], "270", 3))
select_transform(JXFORM_ROT_270);
else
usage();
} else if (keymatch(arg, "scans", 1)) {
/* Set scan script. */
#ifdef C_MULTISCAN_FILES_SUPPORTED
if (++argn >= argc) /* advance to next argument */
@@ -201,6 +319,18 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
exit(EXIT_FAILURE);
#endif
} else if (keymatch(arg, "transpose", 1)) {
/* Transpose (across UL-to-LR axis). */
select_transform(JXFORM_TRANSPOSE);
} else if (keymatch(arg, "transverse", 6)) {
/* Transverse transpose (across UR-to-LL axis). */
select_transform(JXFORM_TRANSVERSE);
} else if (keymatch(arg, "trim", 3)) {
/* Trim off any partial edge MCUs that the transform can't handle. */
transformoption.trim = TRUE;
} else {
usage(); /* bogus switch */
}
@@ -239,10 +369,13 @@ main (int argc, char **argv)
#ifdef PROGRESS_REPORT
struct cdjpeg_progress_mgr progress;
#endif
jvirt_barray_ptr * coef_arrays;
jvirt_barray_ptr * src_coef_arrays;
jvirt_barray_ptr * dst_coef_arrays;
int file_index;
FILE * input_file;
FILE * output_file;
/* We assume all-in-memory processing and can therefore use only a
* single file pointer for sequential input and output operation.
*/
FILE * fp;
/* On Mac, fetch a command line. */
#ifdef USE_CCOMMAND
@@ -269,8 +402,10 @@ main (int argc, char **argv)
/* Scan command line to find file names.
* It is convenient to use just one switch-parsing routine, but the switch
* values read here are ignored; we will rescan the switches after opening
* the input file.
* values read here are mostly ignored; we will rescan the switches after
* opening the input file. Also note that most of the switches affect the
* destination JPEG object, so we parse into that and then copy over what
* needs to affects the source too.
*/
file_index = parse_switches(&dstinfo, argc, argv, 0, FALSE);
@@ -303,24 +438,13 @@ main (int argc, char **argv)
/* Open the input file. */
if (file_index < argc) {
if ((input_file = fopen(argv[file_index], READ_BINARY)) == NULL) {
fprintf(stderr, "%s: can't open %s\n", progname, argv[file_index]);
if ((fp = fopen(argv[file_index], READ_BINARY)) == NULL) {
fprintf(stderr, "%s: can't open %s for reading\n", progname, argv[file_index]);
exit(EXIT_FAILURE);
}
} else {
/* default input file is stdin */
input_file = read_stdin();
}
/* Open the output file. */
if (outfilename != NULL) {
if ((output_file = fopen(outfilename, WRITE_BINARY)) == NULL) {
fprintf(stderr, "%s: can't open %s\n", progname, outfilename);
exit(EXIT_FAILURE);
}
} else {
/* default output file is stdout */
output_file = write_stdout();
fp = read_stdin();
}
#ifdef PROGRESS_REPORT
@@ -328,27 +452,82 @@ main (int argc, char **argv)
#endif
/* Specify data source for decompression */
jpeg_stdio_src(&srcinfo, input_file);
jpeg_stdio_src(&srcinfo, fp);
/* Enable saving of extra markers that we want to copy */
jcopy_markers_setup(&srcinfo, copyoption);
/* Read file header */
(void) jpeg_read_header(&srcinfo, TRUE);
/* Any space needed by a transform option must be requested before
* jpeg_read_coefficients so that memory allocation will be done right.
*/
#if TRANSFORMS_SUPPORTED
/* Fail right away if -perfect is given and transformation is not perfect.
*/
if (!jtransform_request_workspace(&srcinfo, &transformoption)) {
fprintf(stderr, "%s: transformation is not perfect\n", progname);
exit(EXIT_FAILURE);
}
#endif
/* Read source file as DCT coefficients */
coef_arrays = jpeg_read_coefficients(&srcinfo);
src_coef_arrays = jpeg_read_coefficients(&srcinfo);
/* Initialize destination compression parameters from source values */
jpeg_copy_critical_parameters(&srcinfo, &dstinfo);
/* Adjust destination parameters if required by transform options;
* also find out which set of coefficient arrays will hold the output.
*/
#if TRANSFORMS_SUPPORTED
dst_coef_arrays = jtransform_adjust_parameters(&srcinfo, &dstinfo,
src_coef_arrays,
&transformoption);
#else
dst_coef_arrays = src_coef_arrays;
#endif
/* Close input file, if we opened it.
* Note: we assume that jpeg_read_coefficients consumed all input
* until JPEG_REACHED_EOI, and that jpeg_finish_decompress will
* only consume more while (! cinfo->inputctl->eoi_reached).
* We cannot call jpeg_finish_decompress here since we still need the
* virtual arrays allocated from the source object for processing.
*/
if (fp != stdin)
fclose(fp);
/* Open the output file. */
if (outfilename != NULL) {
if ((fp = fopen(outfilename, WRITE_BINARY)) == NULL) {
fprintf(stderr, "%s: can't open %s for writing\n", progname, outfilename);
exit(EXIT_FAILURE);
}
} else {
/* default output file is stdout */
fp = write_stdout();
}
/* Adjust default compression parameters by re-parsing the options */
file_index = parse_switches(&dstinfo, argc, argv, 0, TRUE);
/* Specify data destination for compression */
jpeg_stdio_dest(&dstinfo, output_file);
jpeg_stdio_dest(&dstinfo, fp);
/* Start compressor */
jpeg_write_coefficients(&dstinfo, coef_arrays);
/* Start compressor (note no image data is actually written here) */
jpeg_write_coefficients(&dstinfo, dst_coef_arrays);
/* ought to copy source comments here... */
/* Copy to the output file any extra markers that we want to preserve */
jcopy_markers_execute(&srcinfo, &dstinfo, copyoption);
/* Execute image transformation, if any */
#if TRANSFORMS_SUPPORTED
jtransform_execute_transformation(&srcinfo, &dstinfo,
src_coef_arrays,
&transformoption);
#endif
/* Finish compression and release memory */
jpeg_finish_compress(&dstinfo);
@@ -356,11 +535,9 @@ main (int argc, char **argv)
(void) jpeg_finish_decompress(&srcinfo);
jpeg_destroy_decompress(&srcinfo);
/* Close files, if we opened them */
if (input_file != stdin)
fclose(input_file);
if (output_file != stdout)
fclose(output_file);
/* Close output file, if we opened it */
if (fp != stdout)
fclose(fp);
#ifdef PROGRESS_REPORT
end_progress_monitor((j_common_ptr) &dstinfo);

601
jpegut.c Normal file
View File

@@ -0,0 +1,601 @@
/* Copyright (C)2004 Landmark Graphics Corporation
* Copyright (C)2005 Sun Microsystems, Inc.
* Copyright (C)2009-2010 D. R. Commander
*
* This library is free software and may be redistributed and/or modified under
* the terms of the wxWindows Library License, Version 3.1 or (at your option)
* any later version. The full license is in the LICENSE.txt file included
* with this distribution.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* wxWindows Library License for more details.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "./rrtimer.h"
#include "./turbojpeg.h"
#ifndef _WIN32
#define stricmp strcasecmp
#endif
#define _catch(f) {if((f)==-1) {printf("TJPEG: %s\n", tjGetErrorStr()); bailout();}}
const char *_subnamel[NUMSUBOPT]={"4:4:4", "4:2:2", "4:2:0", "GRAY"};
const char *_subnames[NUMSUBOPT]={"444", "422", "420", "GRAY"};
const int _hsf[NUMSUBOPT]={1, 2, 2, 1};
const int _vsf[NUMSUBOPT]={1, 1, 2, 1};
enum {YUVENCODE=1, YUVDECODE};
int yuv=0;
int exitstatus=0;
#define bailout() {exitstatus=-1; goto finally;}
int pixels[9][3]=
{
{0, 255, 0},
{255, 0, 255},
{255, 255, 0},
{0, 0, 255},
{0, 255, 255},
{255, 0, 0},
{255, 255, 255},
{0, 0, 0},
{255, 0, 0}
};
void initbuf(unsigned char *buf, int w, int h, int ps, int flags)
{
int roffset=(flags&TJ_BGR)?2:0, goffset=1, boffset=(flags&TJ_BGR)?0:2, i,
_i, j;
if(flags&TJ_ALPHAFIRST) {roffset++; goffset++; boffset++;}
memset(buf, 0, w*h*ps);
if(ps==1)
{
for(_i=0; _i<16; _i++)
{
if(flags&TJ_BOTTOMUP) i=h-_i-1; else i=_i;
for(j=0; j<w; j++)
{
if(((_i/8)+(j/8))%2==0) buf[w*i+j]=255;
else buf[w*i+j]=76;
}
}
for(_i=16; _i<h; _i++)
{
if(flags&TJ_BOTTOMUP) i=h-_i-1; else i=_i;
for(j=0; j<w; j++)
{
if(((_i/8)+(j/8))%2==0) buf[w*i+j]=0;
else buf[w*i+j]=226;
}
}
return;
}
for(_i=0; _i<16; _i++)
{
if(flags&TJ_BOTTOMUP) i=h-_i-1; else i=_i;
for(j=0; j<w; j++)
{
buf[(w*i+j)*ps+roffset]=255;
if(((_i/8)+(j/8))%2==0)
{
buf[(w*i+j)*ps+goffset]=255;
buf[(w*i+j)*ps+boffset]=255;
}
}
}
for(_i=16; _i<h; _i++)
{
if(flags&TJ_BOTTOMUP) i=h-_i-1; else i=_i;
for(j=0; j<w; j++)
{
if(((_i/8)+(j/8))%2!=0)
{
buf[(w*i+j)*ps+roffset]=255;
buf[(w*i+j)*ps+goffset]=255;
}
}
}
}
void dumpbuf(unsigned char *buf, int w, int h, int ps, int flags)
{
int roffset=(flags&TJ_BGR)?2:0, goffset=1, boffset=(flags&TJ_BGR)?0:2, i,
j;
for(i=0; i<h; i++)
{
for(j=0; j<w; j++)
{
printf("%.3d/%.3d/%.3d ", buf[(w*i+j)*ps+roffset],
buf[(w*i+j)*ps+roffset], buf[(w*i+j)*ps+roffset]);
}
printf("\n");
}
}
int checkbuf(unsigned char *buf, int w, int h, int ps, int subsamp, int flags)
{
int roffset=(flags&TJ_BGR)?2:0, goffset=1, boffset=(flags&TJ_BGR)?0:2, i,
_i, j;
if(flags&TJ_ALPHAFIRST) {roffset++; goffset++; boffset++;}
if(ps==1) roffset=goffset=boffset=0;
if(subsamp==TJ_GRAYSCALE)
{
for(_i=0; _i<16; _i++)
{
if(flags&TJ_BOTTOMUP) i=h-_i-1; else i=_i;
for(j=0; j<w; j++)
{
unsigned char r=buf[(w*i+j)*ps+roffset],
g=buf[(w*i+j)*ps+goffset],
b=buf[(w*i+j)*ps+boffset];
if(((_i/8)+(j/8))%2==0)
{
if(r<253 || g<253 || b<253) return 0;
}
else
{
if(r<74 || r>78 || g<74 || g>78 || b<74 || b>78) return 0;
}
}
}
for(_i=16; _i<h; _i++)
{
if(flags&TJ_BOTTOMUP) i=h-_i-1; else i=_i;
for(j=0; j<w; j++)
{
unsigned char r=buf[(w*i+j)*ps+roffset],
g=buf[(w*i+j)*ps+goffset],
b=buf[(w*i+j)*ps+boffset];
if(((_i/8)+(j/8))%2==0)
{
if(r>2 || g>2 || b>2) return 0;
}
else
{
if(r<224 || r>228 || g<224 || g>228 || b<224 || b>228) return 0;
}
}
}
}
else
{
for(_i=0; _i<16; _i++)
{
if(flags&TJ_BOTTOMUP) i=h-_i-1; else i=_i;
for(j=0; j<w; j++)
{
if(buf[(w*i+j)*ps+roffset]<253) return 0;
if(((_i/8)+(j/8))%2==0)
{
if(buf[(w*i+j)*ps+goffset]<253) return 0;
if(buf[(w*i+j)*ps+boffset]<253) return 0;
}
else
{
if(buf[(w*i+j)*ps+goffset]>2) return 0;
if(buf[(w*i+j)*ps+boffset]>2) return 0;
}
}
}
for(_i=16; _i<h; _i++)
{
if(flags&TJ_BOTTOMUP) i=h-_i-1; else i=_i;
for(j=0; j<w; j++)
{
if(buf[(w*i+j)*ps+boffset]>2) return 0;
if(((_i/8)+(j/8))%2==0)
{
if(buf[(w*i+j)*ps+roffset]>2) return 0;
if(buf[(w*i+j)*ps+goffset]>2) return 0;
}
else
{
if(buf[(w*i+j)*ps+roffset]<253) return 0;
if(buf[(w*i+j)*ps+goffset]<253) return 0;
}
}
}
}
return 1;
}
#define checkval(v, cv) { \
if(v<cv-1 || v>cv+1) { \
printf("\nComp. %s at %d,%d should be %d, not %d\n", #v, i, j, cv, v); \
retval=0; goto bailout; \
}}
#define checkval0(v) { \
if(v>1) { \
printf("\nComp. %s at %d,%d should be 0, not %d\n", #v, i, j, v); \
retval=0; goto bailout; \
}}
#define checkval255(v) { \
if(v<254 && !(v==217 && i==0 && j==21)) { \
printf("\nComp. %s at %d,%d should be 255, not %d\n", #v, i, j, v); \
retval=0; goto bailout; \
}}
#define PAD(v, p) ((v+(p)-1)&(~((p)-1)))
int checkbufyuv(unsigned char *buf, unsigned long size, int w, int h,
int subsamp)
{
int i, j;
int hsf=_hsf[subsamp], vsf=_vsf[subsamp];
int pw=PAD(w, hsf), ph=PAD(h, vsf);
int cw=pw/hsf, ch=ph/vsf;
int ypitch=PAD(pw, 4), uvpitch=PAD(cw, 4);
int retval=1;
unsigned long correctsize=ypitch*ph + (subsamp==TJ_GRAYSCALE? 0:uvpitch*ch*2);
if(size!=correctsize)
{
printf("\nIncorrect size %lu. Should be %lu\n", size, correctsize);
retval=0; goto bailout;
}
for(i=0; i<16; i++)
{
for(j=0; j<pw; j++)
{
unsigned char y=buf[ypitch*i+j];
if(((i/8)+(j/8))%2==0) checkval255(y)
else checkval(y, 76)
}
}
for(i=16; i<ph; i++)
{
for(j=0; j<pw; j++)
{
unsigned char y=buf[ypitch*i+j];
if(((i/8)+(j/8))%2==0) checkval0(y)
else checkval(y, 226)
}
}
if(subsamp!=TJ_GRAYSCALE)
{
for(i=0; i<16/vsf; i++)
{
for(j=0; j<cw; j++)
{
unsigned char u=buf[ypitch*ph + (uvpitch*i+j)],
v=buf[ypitch*ph + uvpitch*ch + (uvpitch*i+j)];
if(((i*vsf/8)+(j*hsf/8))%2==0)
{
checkval(u, 128); checkval(v, 128);
}
else
{
checkval(u, 85); checkval255(v);
}
}
}
for(i=16/vsf; i<ch; i++)
{
for(j=0; j<cw; j++)
{
unsigned char u=buf[ypitch*ph + (uvpitch*i+j)],
v=buf[ypitch*ph + uvpitch*ch + (uvpitch*i+j)];
if(((i*vsf/8)+(j*hsf/8))%2==0)
{
checkval(u, 128); checkval(v, 128);
}
else
{
checkval0(u); checkval(v, 149);
}
}
}
}
bailout:
if(retval==0)
{
for(i=0; i<ph; i++)
{
for(j=0; j<pw; j++)
printf("%.3d ", buf[ypitch*i+j]);
printf("\n");
}
printf("\n");
for(i=0; i<ch; i++)
{
for(j=0; j<cw; j++)
printf("%.3d ", buf[ypitch*ph + (uvpitch*i+j)]);
printf("\n");
}
printf("\n");
for(i=0; i<ch; i++)
{
for(j=0; j<cw; j++)
printf("%.3d ", buf[ypitch*ph + uvpitch*ch + (uvpitch*i+j)]);
printf("\n");
}
printf("\n");
}
return retval;
}
void writejpeg(unsigned char *jpegbuf, unsigned long jpgbufsize, char *filename)
{
FILE *outfile=NULL;
if((outfile=fopen(filename, "wb"))==NULL)
{
printf("ERROR: Could not open %s for writing.\n", filename);
bailout();
}
if(fwrite(jpegbuf, jpgbufsize, 1, outfile)!=1)
{
printf("ERROR: Could not write to %s.\n", filename);
bailout();
}
finally:
if(outfile) fclose(outfile);
}
void gentestjpeg(tjhandle hnd, unsigned char *jpegbuf, unsigned long *size,
int w, int h, int ps, char *basefilename, int subsamp, int qual, int flags)
{
char tempstr[1024]; unsigned char *bmpbuf=NULL;
const char *pixformat; double t;
if(yuv==YUVENCODE) flags|=TJ_YUV;
if(flags&TJ_BGR)
{
if(ps==3) pixformat="BGR";
else {if(flags&TJ_ALPHAFIRST) pixformat="ABGR"; else pixformat="BGRA";}
}
else
{
if(ps==3) pixformat="RGB";
else {if(flags&TJ_ALPHAFIRST) pixformat="ARGB"; else pixformat="RGBA";}
}
if(ps==1) pixformat="Grayscale";
if(yuv==YUVENCODE)
printf("%s %s -> %s YUV ... ", pixformat,
(flags&TJ_BOTTOMUP)?"Bottom-Up":"Top-Down ", _subnamel[subsamp]);
else
printf("%s %s -> %s Q%d ... ", pixformat,
(flags&TJ_BOTTOMUP)?"Bottom-Up":"Top-Down ", _subnamel[subsamp], qual);
if((bmpbuf=(unsigned char *)malloc(w*h*ps+1))==NULL)
{
printf("ERROR: Could not allocate buffer\n"); bailout();
}
initbuf(bmpbuf, w, h, ps, flags);
memset(jpegbuf, 0, TJBUFSIZE(w, h));
t=rrtime();
_catch(tjCompress(hnd, bmpbuf, w, 0, h, ps, jpegbuf, size, subsamp, qual, flags));
t=rrtime()-t;
if(yuv==YUVENCODE)
sprintf(tempstr, "%s_enc_%s_%s_%s.yuv", basefilename, pixformat,
(flags&TJ_BOTTOMUP)? "BU":"TD", _subnames[subsamp]);
else
sprintf(tempstr, "%s_enc_%s_%s_%sQ%d.jpg", basefilename, pixformat,
(flags&TJ_BOTTOMUP)? "BU":"TD", _subnames[subsamp], qual);
writejpeg(jpegbuf, *size, tempstr);
if(yuv==YUVENCODE)
{
if(checkbufyuv(jpegbuf, *size, w, h, subsamp)) printf("Passed.");
else printf("FAILED!");
}
else printf("Done.");
printf(" %f ms\n Result in %s\n", t*1000., tempstr);
finally:
if(bmpbuf) free(bmpbuf);
}
void gentestbmp(tjhandle hnd, unsigned char *jpegbuf, unsigned long jpegsize,
int w, int h, int ps, char *basefilename, int subsamp, int flags)
{
unsigned char *bmpbuf=NULL;
const char *pixformat; int _w=0, _h=0; double t;
unsigned long size=0;
int hsf=_hsf[subsamp], vsf=_vsf[subsamp];
int pw=PAD(w, hsf), ph=PAD(h, vsf);
int cw=pw/hsf, ch=ph/vsf;
int ypitch=PAD(pw, 4), uvpitch=PAD(cw, 4);
if(yuv==YUVDECODE) flags|=TJ_YUV;
else if(yuv==YUVENCODE) return;
if(flags&TJ_BGR)
{
if(ps==3) pixformat="BGR";
else {if(flags&TJ_ALPHAFIRST) pixformat="ABGR"; else pixformat="BGRA";}
}
else
{
if(ps==3) pixformat="RGB";
else {if(flags&TJ_ALPHAFIRST) pixformat="ARGB"; else pixformat="RGBA";}
}
if(ps==1) pixformat="Grayscale";
if(yuv==YUVDECODE)
printf("JPEG -> YUV %s ... ", _subnames[subsamp]);
else
printf("JPEG -> %s %s ... ", pixformat,
(flags&TJ_BOTTOMUP)?"Bottom-Up":"Top-Down ");
_catch(tjDecompressHeader(hnd, jpegbuf, jpegsize, &_w, &_h));
if(_w!=w || _h!=h)
{
printf("Incorrect JPEG header\n"); bailout();
}
if(yuv==YUVDECODE)
size=ypitch*ph + (subsamp==TJ_GRAYSCALE? 0:uvpitch*ch*2);
else
size=w*h*ps;
if((bmpbuf=(unsigned char *)malloc(size+1))==NULL)
{
printf("ERROR: Could not allocate buffer\n"); bailout();
}
memset(bmpbuf, 0, size+1);
t=rrtime();
_catch(tjDecompress(hnd, jpegbuf, jpegsize, bmpbuf, w, w*ps, h, ps, flags));
t=rrtime()-t;
if(yuv==YUVDECODE)
{
if(checkbufyuv(bmpbuf, size, pw, ph, subsamp))
printf("Passed.");
else printf("FAILED!");
}
else
{
if(checkbuf(bmpbuf, w, h, ps, subsamp, flags)) printf("Passed.");
else {printf("FAILED!"); dumpbuf(bmpbuf, w, h, ps, flags);}
}
printf(" %f ms\n\n", t*1000.);
finally:
if(bmpbuf) free(bmpbuf);
}
void dotest(int w, int h, int ps, int subsamp, char *basefilename)
{
tjhandle hnd=NULL, dhnd=NULL; unsigned char *jpegbuf=NULL;
unsigned long size;
if((jpegbuf=(unsigned char *)malloc(TJBUFSIZE(w, h))) == NULL)
{
puts("ERROR: Could not allocate buffer."); bailout();
}
if((hnd=tjInitCompress())==NULL)
{printf("Error in tjInitCompress():\n%s\n", tjGetErrorStr()); bailout();}
if((dhnd=tjInitDecompress())==NULL)
{printf("Error in tjInitDecompress():\n%s\n", tjGetErrorStr()); bailout();}
gentestjpeg(hnd, jpegbuf, &size, w, h, ps, basefilename, subsamp, 100, 0);
gentestbmp(dhnd, jpegbuf, size, w, h, ps, basefilename, subsamp, 0);
if(ps==1 || yuv==YUVDECODE) goto finally;
gentestjpeg(hnd, jpegbuf, &size, w, h, ps, basefilename, subsamp, 100, TJ_BGR);
gentestbmp(dhnd, jpegbuf, size, w, h, ps, basefilename, subsamp, TJ_BGR);
gentestjpeg(hnd, jpegbuf, &size, w, h, ps, basefilename, subsamp, 100, TJ_BOTTOMUP);
gentestbmp(dhnd, jpegbuf, size, w, h, ps, basefilename, subsamp, TJ_BOTTOMUP);
gentestjpeg(hnd, jpegbuf, &size, w, h, ps, basefilename, subsamp, 100, TJ_BGR|TJ_BOTTOMUP);
gentestbmp(dhnd, jpegbuf, size, w, h, ps, basefilename, subsamp, TJ_BGR|TJ_BOTTOMUP);
if(ps==4)
{
gentestjpeg(hnd, jpegbuf, &size, w, h, ps, basefilename, subsamp, 100, TJ_ALPHAFIRST);
gentestbmp(dhnd, jpegbuf, size, w, h, ps, basefilename, subsamp, TJ_ALPHAFIRST);
gentestjpeg(hnd, jpegbuf, &size, w, h, ps, basefilename, subsamp, 100, TJ_ALPHAFIRST|TJ_BGR);
gentestbmp(dhnd, jpegbuf, size, w, h, ps, basefilename, subsamp, TJ_ALPHAFIRST|TJ_BGR);
gentestjpeg(hnd, jpegbuf, &size, w, h, ps, basefilename, subsamp, 100, TJ_ALPHAFIRST|TJ_BOTTOMUP);
gentestbmp(dhnd, jpegbuf, size, w, h, ps, basefilename, subsamp, TJ_ALPHAFIRST|TJ_BOTTOMUP);
gentestjpeg(hnd, jpegbuf, &size, w, h, ps, basefilename, subsamp, 100, TJ_ALPHAFIRST|TJ_BGR|TJ_BOTTOMUP);
gentestbmp(dhnd, jpegbuf, size, w, h, ps, basefilename, subsamp, TJ_ALPHAFIRST|TJ_BGR|TJ_BOTTOMUP);
}
finally:
if(hnd) tjDestroy(hnd);
if(dhnd) tjDestroy(dhnd);
if(jpegbuf) free(jpegbuf);
}
#define MAXLENGTH 2048
void dotest1(void)
{
int i, j, i2; unsigned char *bmpbuf=NULL, *jpgbuf=NULL;
tjhandle hnd=NULL; unsigned long size;
if((hnd=tjInitCompress())==NULL)
{printf("Error in tjInitCompress():\n%s\n", tjGetErrorStr()); bailout();}
printf("Buffer size regression test\n");
for(j=1; j<48; j++)
{
for(i=1; i<(j==1?MAXLENGTH:48); i++)
{
if(i%100==0) printf("%.4d x %.4d\b\b\b\b\b\b\b\b\b\b\b", i, j);
if((bmpbuf=(unsigned char *)malloc(i*j*4))==NULL
|| (jpgbuf=(unsigned char *)malloc(TJBUFSIZE(i, j)))==NULL)
{
printf("Memory allocation failure\n"); bailout();
}
memset(bmpbuf, 0, i*j*4);
for(i2=0; i2<i*j; i2++)
{
bmpbuf[i2*4]=pixels[i2%9][2];
bmpbuf[i2*4+1]=pixels[i2%9][1];
bmpbuf[i2*2+2]=pixels[i2%9][0];
}
_catch(tjCompress(hnd, bmpbuf, i, i*4, j, 4,
jpgbuf, &size, TJ_444, 100, TJ_BGR));
free(bmpbuf); bmpbuf=NULL; free(jpgbuf); jpgbuf=NULL;
if((bmpbuf=(unsigned char *)malloc(j*i*4))==NULL
|| (jpgbuf=(unsigned char *)malloc(TJBUFSIZE(j, i)))==NULL)
{
printf("Memory allocation failure\n"); bailout();
}
for(i2=0; i2<j*i*4; i2++)
{
if(i2%2==0) bmpbuf[i2]=0xFF;
else bmpbuf[i2]=0;
}
_catch(tjCompress(hnd, bmpbuf, j, j*4, i, 4,
jpgbuf, &size, TJ_444, 100, TJ_BGR));
free(bmpbuf); bmpbuf=NULL; free(jpgbuf); jpgbuf=NULL;
}
}
printf("Done. \n");
finally:
if(bmpbuf) free(bmpbuf); if(jpgbuf) free(jpgbuf);
if(hnd) tjDestroy(hnd);
}
int main(int argc, char *argv[])
{
int doyuv=0;
if(argc>1 && !stricmp(argv[1], "-yuv")) doyuv=1;
if(doyuv) yuv=YUVENCODE;
dotest(35, 39, 3, TJ_444, "test");
dotest(39, 41, 4, TJ_444, "test");
if(doyuv)
{
dotest(41, 35, 3, TJ_422, "test");
dotest(35, 39, 4, TJ_422, "test");
dotest(39, 41, 3, TJ_420, "test");
dotest(41, 35, 4, TJ_420, "test");
}
dotest(35, 39, 1, TJ_GRAYSCALE, "test");
dotest(39, 41, 3, TJ_GRAYSCALE, "test");
dotest(41, 35, 4, TJ_GRAYSCALE, "test");
if(!doyuv) dotest1();
if(doyuv)
{
yuv=YUVDECODE;
dotest(48, 48, 3, TJ_444, "test");
dotest(35, 39, 3, TJ_444, "test");
dotest(48, 48, 1, TJ_GRAYSCALE, "test");
dotest(39, 41, 1, TJ_GRAYSCALE, "test");
}
return exitstatus;
}

574
jpgtest.cxx Normal file
View File

@@ -0,0 +1,574 @@
/* Copyright (C)2004 Landmark Graphics Corporation
* Copyright (C)2005, 2006 Sun Microsystems, Inc.
* Copyright (C)2009-2010 D. R. Commander
*
* This library is free software and may be redistributed and/or modified under
* the terms of the wxWindows Library License, Version 3.1 or (at your option)
* any later version. The full license is in the LICENSE.txt file included
* with this distribution.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* wxWindows Library License for more details.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <errno.h>
#include "./bmp.h"
#include "./rrutil.h"
#include "./rrtimer.h"
#include "./turbojpeg.h"
#define _throw(op, err) { \
printf("ERROR in line %d while %s:\n%s\n", __LINE__, op, err); goto bailout;}
#define _throwunix(m) _throw(m, strerror(errno))
#define _throwtj(m) _throw(m, tjGetErrorStr())
#define _throwbmp(m) _throw(m, bmpgeterr())
#define PAD(v, p) ((v+(p)-1)&(~((p)-1)))
enum {YUVENCODE=1, YUVDECODE};
int forcemmx=0, forcesse=0, forcesse2=0, forcesse3=0, fastupsample=0,
decomponly=0, yuv=0;
const int _ps[BMPPIXELFORMATS]={3, 4, 3, 4, 4, 4};
const int _flags[BMPPIXELFORMATS]={0, 0, TJ_BGR, TJ_BGR,
TJ_BGR|TJ_ALPHAFIRST, TJ_ALPHAFIRST};
const int _rindex[BMPPIXELFORMATS]={0, 0, 2, 2, 3, 1};
const int _gindex[BMPPIXELFORMATS]={1, 1, 1, 1, 2, 2};
const int _bindex[BMPPIXELFORMATS]={2, 2, 0, 0, 1, 3};
const char *_pfname[]={"RGB", "RGBA", "BGR", "BGRA", "ABGR", "ARGB"};
const char *_subnamel[NUMSUBOPT]={"4:4:4", "4:2:2", "4:2:0", "GRAY"};
const char *_subnames[NUMSUBOPT]={"444", "422", "420", "GRAY"};
const int _hsf[NUMSUBOPT]={1, 2, 2, 1};
const int _vsf[NUMSUBOPT]={1, 1, 2, 1};
void printsigfig(double val, int figs)
{
char format[80];
double _l=log10(val); int l;
if(_l<0.)
{
l=(int)fabs(_l);
sprintf(format, "%%%d.%df", figs+l+2, figs+l);
}
else
{
l=(int)_l+1;
if(figs<=l) sprintf(format, "%%.0f");
else sprintf(format, "%%%d.%df", figs+1, figs-l);
}
printf(format, val);
}
void dotest(unsigned char *srcbuf, int w, int h, BMPPIXELFORMAT pf, int bu,
int jpegsub, int qual, char *filename, int dotile, int useppm, int quiet)
{
char tempstr[1024];
FILE *outfile=NULL; tjhandle hnd;
unsigned char **jpegbuf=NULL, *rgbbuf=NULL;
rrtimer timer; double elapsed;
int jpgbufsize=0, i, j, tilesizex, tilesizey, numtilesx, numtilesy, ITER;
unsigned long *comptilesize=NULL;
int flags=(forcemmx?TJ_FORCEMMX:0)|(forcesse?TJ_FORCESSE:0)
|(forcesse2?TJ_FORCESSE2:0)|(forcesse3?TJ_FORCESSE3:0)
|(fastupsample?TJ_FASTUPSAMPLE:0);
int ps=_ps[pf];
int pitch=w*ps, yuvsize;
int hsf=_hsf[jpegsub], vsf=_vsf[jpegsub];
int pw=PAD(w, hsf), ph=PAD(h, vsf);
int cw=pw/hsf, ch=ph/vsf;
int ypitch=PAD(pw, 4), uvpitch=PAD(cw, 4);
flags |= _flags[pf];
if(bu) flags |= TJ_BOTTOMUP;
if(yuv==YUVENCODE) flags |= TJ_YUV;
yuvsize=ypitch*ph + (jpegsub==TJ_GRAYSCALE? 0:uvpitch*ch*2);
if((rgbbuf=(unsigned char *)malloc(max(yuvsize, pitch*h))) == NULL)
_throwunix("allocating image buffer");
if(!quiet)
{
if(yuv==YUVENCODE)
printf("\n>>>>> %s (%s) <--> YUV %s <<<<<\n", _pfname[pf],
bu?"Bottom-up":"Top-down", _subnamel[jpegsub]);
else
printf("\n>>>>> %s (%s) <--> JPEG %s Q%d <<<<<\n", _pfname[pf],
bu?"Bottom-up":"Top-down", _subnamel[jpegsub], qual);
}
if(yuv==YUVDECODE) dotile=0;
if(dotile) {tilesizex=tilesizey=4;} else {tilesizex=w; tilesizey=h;}
do
{
tilesizex*=2; if(tilesizex>w) tilesizex=w;
tilesizey*=2; if(tilesizey>h) tilesizey=h;
numtilesx=(w+tilesizex-1)/tilesizex;
numtilesy=(h+tilesizey-1)/tilesizey;
if((comptilesize=(unsigned long *)malloc(sizeof(unsigned long)*numtilesx*numtilesy)) == NULL
|| (jpegbuf=(unsigned char **)malloc(sizeof(unsigned char *)*numtilesx*numtilesy)) == NULL)
_throwunix("allocating image buffers");
memset(jpegbuf, 0, sizeof(unsigned char *)*numtilesx*numtilesy);
for(i=0; i<numtilesx*numtilesy; i++)
{
if((jpegbuf[i]=(unsigned char *)malloc(TJBUFSIZE(tilesizex, tilesizey))) == NULL)
_throwunix("allocating image buffers");
}
// Compression test
if(quiet) printf("%s\t%s\t%s\t%d\t", _pfname[pf], bu?"BU":"TD",
_subnamel[jpegsub], qual);
for(i=0; i<h; i++) memcpy(&rgbbuf[pitch*i], &srcbuf[w*ps*i], w*ps);
if((hnd=tjInitCompress())==NULL)
_throwtj("executing tjInitCompress()");
if(tjCompress(hnd, rgbbuf, tilesizex, pitch, tilesizey, ps,
jpegbuf[0], &comptilesize[0], jpegsub, qual, flags)==-1)
_throwtj("executing tjCompress()");
ITER=0;
timer.start();
do
{
jpgbufsize=0; int tilen=0;
for(i=0; i<h; i+=tilesizey)
{
for(j=0; j<w; j+=tilesizex)
{
int tempw=min(tilesizex, w-j), temph=min(tilesizey, h-i);
if(tjCompress(hnd, &rgbbuf[pitch*i+j*ps], tempw, pitch,
temph, ps, jpegbuf[tilen], &comptilesize[tilen], jpegsub, qual,
flags)==-1)
_throwtj("executing tjCompress()");
jpgbufsize+=comptilesize[tilen];
tilen++;
}
}
ITER++;
} while((elapsed=timer.elapsed())<5.);
if(tjDestroy(hnd)==-1) _throwtj("executing tjDestroy()");
hnd=NULL;
if(quiet)
{
if(tilesizex==w && tilesizey==h) printf("Full \t");
else printf("%-4d %-4d\t", tilesizex, tilesizey);
printsigfig((double)(w*h)/1000000.*(double)ITER/elapsed, 4);
printf("\t");
printsigfig((double)(w*h*ps)/(double)jpgbufsize, 4);
printf("\t");
}
else
{
if(tilesizex==w && tilesizey==h) printf("\nFull image\n");
else printf("\nTile size: %d x %d\n", tilesizex, tilesizey);
printf("C--> Frame rate: %f fps\n", (double)ITER/elapsed);
printf(" Output image size: %d bytes\n", jpgbufsize);
printf(" Compression ratio: %f:1\n",
(double)(w*h*ps)/(double)jpgbufsize);
printf(" Source throughput: %f Megapixels/sec\n",
(double)(w*h)/1000000.*(double)ITER/elapsed);
printf(" Output bit stream: %f Megabits/sec\n",
(double)jpgbufsize*8./1000000.*(double)ITER/elapsed);
}
if(tilesizex==w && tilesizey==h)
{
if(yuv==YUVENCODE)
sprintf(tempstr, "%s_%s.yuv", filename, _subnames[jpegsub]);
else
sprintf(tempstr, "%s_%sQ%d.jpg", filename, _subnames[jpegsub], qual);
if((outfile=fopen(tempstr, "wb"))==NULL)
_throwunix("opening reference image");
if(fwrite(jpegbuf[0], jpgbufsize, 1, outfile)!=1)
_throwunix("writing reference image");
fclose(outfile); outfile=NULL;
if(!quiet) printf("Reference image written to %s\n", tempstr);
}
if(yuv==YUVENCODE) goto bailout;
// Decompression test
if(yuv==YUVDECODE) flags |= TJ_YUV;
memset(rgbbuf, 127, max(yuvsize, pitch*h)); // Grey image means decompressor did nothing
if((hnd=tjInitDecompress())==NULL)
_throwtj("executing tjInitDecompress()");
if(tjDecompress(hnd, jpegbuf[0], jpgbufsize, rgbbuf, tilesizex, pitch,
tilesizey, ps, flags)==-1)
_throwtj("executing tjDecompress()");
ITER=0;
timer.start();
do
{
int tilen=0;
for(i=0; i<h; i+=tilesizey)
{
for(j=0; j<w; j+=tilesizex)
{
int tempw=min(tilesizex, w-j), temph=min(tilesizey, h-i);
if(tjDecompress(hnd, jpegbuf[tilen], comptilesize[tilen],
&rgbbuf[pitch*i+ps*j], tempw, pitch, temph, ps, flags)==-1)
_throwtj("executing tjDecompress()");
tilen++;
}
}
ITER++;
} while((elapsed=timer.elapsed())<5.);
if(tjDestroy(hnd)==-1) _throwtj("executing tjDestroy()");
hnd=NULL;
if(quiet)
{
printsigfig((double)(w*h)/1000000.*(double)ITER/elapsed, 4);
printf("\n");
}
else
{
printf("D--> Frame rate: %f fps\n", (double)ITER/elapsed);
printf(" Dest. throughput: %f Megapixels/sec\n",
(double)(w*h)/1000000.*(double)ITER/elapsed);
}
if(yuv==YUVDECODE)
{
sprintf(tempstr, "%s_%sQ%d.yuv", filename, _subnames[jpegsub], qual);
if((outfile=fopen(tempstr, "wb"))==NULL)
_throwunix("opening YUV image for output");
if(fwrite(rgbbuf, yuvsize, 1, outfile)!=1)
_throwunix("writing YUV image");
fclose(outfile); outfile=NULL;
}
else
{
if(tilesizex==w && tilesizey==h)
sprintf(tempstr, "%s_%sQ%d_full.%s", filename, _subnames[jpegsub], qual,
useppm?"ppm":"bmp");
else sprintf(tempstr, "%s_%sQ%d_%dx%d.%s", filename, _subnames[jpegsub],
qual, tilesizex, tilesizey, useppm?"ppm":"bmp");
if(savebmp(tempstr, rgbbuf, w, h, pf, pitch, bu)==-1)
_throwbmp("saving bitmap");
sprintf(strrchr(tempstr, '.'), "-err.%s", useppm?"ppm":"bmp");
if(!quiet)
printf("Computing compression error and saving to %s.\n", tempstr);
if(jpegsub==TJ_GRAYSCALE)
{
for(j=0; j<h; j++)
{
for(i=0; i<w*ps; i+=ps)
{
int y=(int)((double)srcbuf[w*ps*j+i+_rindex[pf]]*0.299
+ (double)srcbuf[w*ps*j+i+_gindex[pf]]*0.587
+ (double)srcbuf[w*ps*j+i+_bindex[pf]]*0.114 + 0.5);
if(y>255) y=255; if(y<0) y=0;
rgbbuf[pitch*j+i+_rindex[pf]]=abs(rgbbuf[pitch*j+i+_rindex[pf]]-y);
rgbbuf[pitch*j+i+_gindex[pf]]=abs(rgbbuf[pitch*j+i+_gindex[pf]]-y);
rgbbuf[pitch*j+i+_bindex[pf]]=abs(rgbbuf[pitch*j+i+_bindex[pf]]-y);
}
}
}
else
{
for(j=0; j<h; j++) for(i=0; i<w*ps; i++)
rgbbuf[pitch*j+i]=abs(rgbbuf[pitch*j+i]-srcbuf[w*ps*j+i]);
}
if(savebmp(tempstr, rgbbuf, w, h, pf, pitch, bu)==-1)
_throwbmp("saving bitmap");
}
// Cleanup
if(outfile) {fclose(outfile); outfile=NULL;}
if(jpegbuf)
{
for(i=0; i<numtilesx*numtilesy; i++)
{if(jpegbuf[i]) free(jpegbuf[i]); jpegbuf[i]=NULL;}
free(jpegbuf); jpegbuf=NULL;
}
if(comptilesize) {free(comptilesize); comptilesize=NULL;}
} while(tilesizex<w || tilesizey<h);
if(rgbbuf) {free(rgbbuf); rgbbuf=NULL;}
return;
bailout:
if(outfile) {fclose(outfile); outfile=NULL;}
if(jpegbuf)
{
for(i=0; i<numtilesx*numtilesy; i++)
{if(jpegbuf[i]) free(jpegbuf[i]); jpegbuf[i]=NULL;}
free(jpegbuf); jpegbuf=NULL;
}
if(comptilesize) {free(comptilesize); comptilesize=NULL;}
if(rgbbuf) {free(rgbbuf); rgbbuf=NULL;}
if(hnd) {tjDestroy(hnd); hnd=NULL;}
return;
}
void dodecomptest(char *filename, BMPPIXELFORMAT pf, int bu, int useppm,
int quiet)
{
char tempstr[1024];
FILE *file=NULL; tjhandle hnd;
unsigned char *jpegbuf=NULL, *rgbbuf=NULL;
rrtimer timer; double elapsed;
int w, h, ITER;
unsigned long jpgbufsize=0;
int flags=(forcemmx?TJ_FORCEMMX:0)|(forcesse?TJ_FORCESSE:0)
|(forcesse2?TJ_FORCESSE2:0)|(forcesse3?TJ_FORCESSE3:0)
|(fastupsample?TJ_FASTUPSAMPLE:0);
int ps=_ps[pf], pitch, jpegsub=-1;
char *temp=NULL;
int hsf, vsf, pw, ph, cw, ch, ypitch, uvpitch, yuvsize;
flags |= _flags[pf];
if(bu) flags |= TJ_BOTTOMUP;
if(yuv==YUVDECODE) flags |= TJ_YUV;
if((file=fopen(filename, "rb"))==NULL)
_throwunix("opening file");
if(fseek(file, 0, SEEK_END)<0 || (jpgbufsize=ftell(file))<0)
_throwunix("determining file size");
if((jpegbuf=(unsigned char *)malloc(jpgbufsize))==NULL)
_throwunix("allocating memory");
if(fseek(file, 0, SEEK_SET)<0)
_throwunix("setting file position");
if(fread(jpegbuf, jpgbufsize, 1, file)<1)
_throwunix("reading JPEG data");
fclose(file); file=NULL;
temp=strrchr(filename, '.');
if(temp!=NULL) *temp='\0';
if((hnd=tjInitDecompress())==NULL) _throwtj("executing tjInitDecompress()");
if(tjDecompressHeader2(hnd, jpegbuf, jpgbufsize, &w, &h, &jpegsub)==-1)
_throwtj("executing tjDecompressHeader2()");
hsf=_hsf[jpegsub], vsf=_vsf[jpegsub];
pw=PAD(w, hsf), ph=PAD(h, vsf);
cw=pw/hsf, ch=ph/vsf;
ypitch=PAD(pw, 4), uvpitch=PAD(cw, 4);
yuvsize=ypitch*ph + (jpegsub==TJ_GRAYSCALE? 0:uvpitch*ch*2);
pitch=w*ps;
if(quiet)
{
printf("All performance values in Mpixels/sec\n\n");
printf("Bitmap\tBitmap\tImage Size\tDecomp\n"),
printf("Format\tOrder\t X Y \tPerf\n\n");
printf("%s\t%s\t%-4d %-4d\t", _pfname[pf], bu?"BU":"TD", w, h);
}
if((rgbbuf=(unsigned char *)malloc(max(yuvsize, pitch*h)))==NULL)
_throwunix("allocating image buffer");
if(!quiet)
{
if(yuv==YUVDECODE)
printf("\n>>>>> JPEG --> YUV %s <<<<<\n", _subnamel[jpegsub]);
else
printf("\n>>>>> JPEG --> %s (%s) <<<<<\n", _pfname[pf],
bu?"Bottom-up":"Top-down");
printf("\nImage size: %d x %d\n", w, h);
}
memset(rgbbuf, 127, max(yuvsize, pitch*h)); // Grey image means decompressor did nothing
if(tjDecompress(hnd, jpegbuf, jpgbufsize, rgbbuf, w, pitch, h, ps, flags)==-1)
_throwtj("executing tjDecompress()");
ITER=0;
timer.start();
do
{
if(tjDecompress(hnd, jpegbuf, jpgbufsize, rgbbuf, w, pitch, h, ps, flags)
==-1)
_throwtj("executing tjDecompress()");
ITER++;
} while((elapsed=timer.elapsed())<5.);
if(tjDestroy(hnd)==-1) _throwtj("executing tjDestroy()");
hnd=NULL;
if(quiet)
{
printsigfig((double)(w*h)/1000000.*(double)ITER/elapsed, 4);
printf("\n");
}
else
{
printf("D--> Frame rate: %f fps\n", (double)ITER/elapsed);
printf(" Dest. throughput: %f Megapixels/sec\n",
(double)(w*h)/1000000.*(double)ITER/elapsed);
}
sprintf(tempstr, "%s_full.%s", filename, useppm?"ppm":"bmp");
if(yuv==YUVDECODE)
{
sprintf(tempstr, "%s_%s.yuv", filename, _subnames[jpegsub]);
if((file=fopen(tempstr, "wb"))==NULL)
_throwunix("opening YUV image for output");
if(fwrite(rgbbuf, yuvsize, 1, file)!=1)
_throwunix("writing YUV image");
fclose(file); file=NULL;
}
else
{
if(savebmp(tempstr, rgbbuf, w, h, pf, pitch, bu)==-1)
_throwbmp("saving bitmap");
}
bailout:
if(file) {fclose(file); file=NULL;}
if(jpegbuf) {free(jpegbuf); jpegbuf=NULL;}
if(rgbbuf) {free(rgbbuf); rgbbuf=NULL;}
if(hnd) {tjDestroy(hnd); hnd=NULL;}
return;
}
void usage(char *progname)
{
printf("USAGE: %s <Inputfile (BMP|PPM))> <%% Quality>\n", progname);
printf(" %s <Inputfile (JPG))>\n\n", progname);
printf(" [-tile]\n");
printf(" Test performance of the codec when the image is encoded\n");
printf(" as separate tiles of varying sizes.\n\n");
printf(" [-forcemmx] [-forcesse] [-forcesse2] [-forcesse3]\n");
printf(" Force MMX, SSE, or SSE2 code paths in Intel codec\n\n");
printf(" [-rgb | -bgr | -rgba | -bgra | -abgr | -argb]\n");
printf(" Test the specified color conversion path in the codec (default: BGR)\n\n");
printf(" [-fastupsample]\n");
printf(" Use fast, inaccurate upsampling code to perform 4:2:2 and 4:2:0\n");
printf(" YUV decoding in libjpeg decompressor\n\n");
printf(" [-quiet]\n");
printf(" Output in tabular rather than verbose format\n\n");
printf(" [-yuvencode]\n");
printf(" Encode RGB input as planar YUV rather than compressing as JPEG\n\n");
printf(" [-yuvdecode]\n");
printf(" Decode JPEG image to planar YUV rather than RGB\n\n");
printf(" NOTE: If the quality is specified as a range, i.e. 90-100, a separate\n");
printf(" test will be performed for all quality values in the range.\n");
exit(1);
}
int main(int argc, char *argv[])
{
unsigned char *bmpbuf=NULL; int w, h, i, useppm=0;
int qual, dotile=0, quiet=0, hiqual=-1; char *temp;
BMPPIXELFORMAT pf=BMP_BGR;
int bu=0, minarg=2;
printf("\n");
if(argc<minarg) usage(argv[0]);
temp=strrchr(argv[1], '.');
if(temp!=NULL)
{
if(!stricmp(temp, ".ppm")) useppm=1;
if(!stricmp(temp, ".jpg") || !stricmp(temp, ".jpeg")) decomponly=1;
}
if(argc>minarg)
{
for(i=minarg; i<argc; i++)
{
if(!stricmp(argv[i], "-yuvencode"))
{
printf("Testing YUV planar encoding\n");
yuv=YUVENCODE; hiqual=qual=100;
}
if(!stricmp(argv[i], "-yuvdecode"))
{
printf("Testing YUV planar decoding\n");
yuv=YUVDECODE;
}
}
}
if(!decomponly && yuv!=YUVENCODE)
{
minarg=3;
if(argc<minarg) usage(argv[0]);
if((qual=atoi(argv[2]))<1 || qual>100)
{
puts("ERROR: Quality must be between 1 and 100.");
exit(1);
}
if((temp=strchr(argv[2], '-'))!=NULL && strlen(temp)>1
&& sscanf(&temp[1], "%d", &hiqual)==1 && hiqual>qual && hiqual>=1
&& hiqual<=100) {}
else hiqual=qual;
}
if(argc>minarg)
{
for(i=minarg; i<argc; i++)
{
if(!stricmp(argv[i], "-tile")) dotile=1;
if(!stricmp(argv[i], "-forcesse3"))
{
printf("Using SSE3 code\n");
forcesse3=1;
}
if(!stricmp(argv[i], "-forcesse2"))
{
printf("Using SSE2 code\n");
forcesse2=1;
}
if(!stricmp(argv[i], "-forcesse"))
{
printf("Using SSE code\n");
forcesse=1;
}
if(!stricmp(argv[i], "-forcemmx"))
{
printf("Using MMX code\n");
forcemmx=1;
}
if(!stricmp(argv[i], "-fastupsample"))
{
printf("Using fast upsampling code\n");
fastupsample=1;
}
if(!stricmp(argv[i], "-rgb")) pf=BMP_RGB;
if(!stricmp(argv[i], "-rgba")) pf=BMP_RGBA;
if(!stricmp(argv[i], "-bgr")) pf=BMP_BGR;
if(!stricmp(argv[i], "-bgra")) pf=BMP_BGRA;
if(!stricmp(argv[i], "-abgr")) pf=BMP_ABGR;
if(!stricmp(argv[i], "-argb")) pf=BMP_ARGB;
if(!stricmp(argv[i], "-bottomup")) bu=1;
if(!stricmp(argv[i], "-quiet")) quiet=1;
}
}
if(!decomponly)
{
if(loadbmp(argv[1], &bmpbuf, &w, &h, pf, 1, bu)==-1)
_throwbmp("loading bitmap");
temp=strrchr(argv[1], '.');
if(temp!=NULL) *temp='\0';
}
if(quiet && !decomponly)
{
printf("All performance values in Mpixels/sec\n\n");
printf("Bitmap\tBitmap\tJPEG\tJPEG\tTile Size\tCompr\tCompr\tDecomp\n");
printf("Format\tOrder\tFormat\tQual\t X Y \tPerf \tRatio\tPerf\n\n");
}
if(decomponly)
{
dodecomptest(argv[1], pf, bu, 1, quiet);
goto bailout;
}
for(i=hiqual; i>=qual; i--)
dotest(bmpbuf, w, h, pf, bu, TJ_GRAYSCALE, i, argv[1], dotile, useppm, quiet);
if(quiet) printf("\n");
for(i=hiqual; i>=qual; i--)
dotest(bmpbuf, w, h, pf, bu, TJ_420, i, argv[1], dotile, useppm, quiet);
if(quiet) printf("\n");
for(i=hiqual; i>=qual; i--)
dotest(bmpbuf, w, h, pf, bu, TJ_422, i, argv[1], dotile, useppm, quiet);
if(quiet) printf("\n");
for(i=hiqual; i>=qual; i--)
dotest(bmpbuf, w, h, pf, bu, TJ_444, i, argv[1], dotile, useppm, quiet);
bailout:
if(bmpbuf) free(bmpbuf);
return 0;
}

View File

@@ -2,6 +2,7 @@
* jquant1.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Copyright (C) 2009, 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.
*
@@ -193,7 +194,10 @@ select_ncolors (j_decompress_ptr cinfo, int Ncolors[])
int total_colors, iroot, i, j;
boolean changed;
long temp;
static const int RGB_order[3] = { RGB_GREEN, RGB_RED, RGB_BLUE };
int RGB_order[3] = { RGB_GREEN, RGB_RED, RGB_BLUE };
RGB_order[0] = rgb_green[cinfo->out_color_space];
RGB_order[1] = rgb_red[cinfo->out_color_space];
RGB_order[2] = rgb_blue[cinfo->out_color_space];
/* We can allocate at least the nc'th root of max_colors per component. */
/* Compute floor(nc'th root of max_colors). */

View File

@@ -2,6 +2,7 @@
* jquant2.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Copyright (C) 2009, 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.
*
@@ -74,29 +75,10 @@
#define G_SCALE 3 /* scale G distances by this much */
#define B_SCALE 1 /* and B by this much */
/* Relabel R/G/B as components 0/1/2, respecting the RGB ordering defined
* in jmorecfg.h. As the code stands, it will do the right thing for R,G,B
* and B,G,R orders. If you define some other weird order in jmorecfg.h,
* you'll get compile errors until you extend this logic. In that case
* you'll probably want to tweak the histogram sizes too.
*/
#if RGB_RED == 0
#define C0_SCALE R_SCALE
#endif
#if RGB_BLUE == 0
#define C0_SCALE B_SCALE
#endif
#if RGB_GREEN == 1
#define C1_SCALE G_SCALE
#endif
#if RGB_RED == 2
#define C2_SCALE R_SCALE
#endif
#if RGB_BLUE == 2
#define C2_SCALE B_SCALE
#endif
static const int c_scales[3]={R_SCALE, G_SCALE, B_SCALE};
#define C0_SCALE c_scales[rgb_red[cinfo->out_color_space]]
#define C1_SCALE c_scales[rgb_green[cinfo->out_color_space]]
#define C2_SCALE c_scales[rgb_blue[cinfo->out_color_space]]
/*
* First we have the histogram data structure and routines for creating it.
@@ -454,15 +436,16 @@ median_cut (j_decompress_ptr cinfo, boxptr boxlist, int numboxes,
/* We want to break any ties in favor of green, then red, blue last.
* This code does the right thing for R,G,B or B,G,R color orders only.
*/
#if RGB_RED == 0
cmax = c1; n = 1;
if (c0 > cmax) { cmax = c0; n = 0; }
if (c2 > cmax) { n = 2; }
#else
cmax = c1; n = 1;
if (c2 > cmax) { cmax = c2; n = 2; }
if (c0 > cmax) { n = 0; }
#endif
if (rgb_red[cinfo->out_color_space] == 0) {
cmax = c1; n = 1;
if (c0 > cmax) { cmax = c0; n = 0; }
if (c2 > cmax) { n = 2; }
}
else {
cmax = c1; n = 1;
if (c2 > cmax) { cmax = c2; n = 2; }
if (c0 > cmax) { n = 0; }
}
/* Choose split point along selected axis, and update box bounds.
* Current algorithm: split at halfway point.
* (Since the box has been shrunk to minimum volume,

89
jsimd.h Normal file
View File

@@ -0,0 +1,89 @@
/*
* jsimd.h
*
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
*
* Based on the x86 SIMD extension for IJG JPEG library,
* Copyright (C) 1999-2006, MIYASAKA Masaru.
*
*/
/* Short forms of external names for systems with brain-damaged linkers. */
#ifdef NEED_SHORT_EXTERNAL_NAMES
#define jsimd_can_rgb_ycc jSCanRgbYcc
#define jsimd_can_ycc_rgb jSCanYccRgb
#define jsimd_rgb_ycc_convert jSRgbYccConv
#define jsimd_ycc_rgb_convert jSYccRgbConv
#define jsimd_can_h2v2_downsample jSCanH2V2Down
#define jsimd_can_h2v1_downsample jSCanH2V1Down
#define jsimd_h2v2_downsample jSH2V2Down
#define jsimd_h2v1_downsample jSH2V1Down
#define jsimd_can_h2v2_upsample jSCanH2V2Up
#define jsimd_can_h2v1_upsample jSCanH2V1Up
#define jsimd_h2v2_upsample jSH2V2Up
#define jsimd_h2v1_upsample jSH2V1Up
#define jsimd_can_h2v2_fancy_upsample jSCanH2V2FUp
#define jsimd_can_h2v1_fancy_upsample jSCanH2V1FUp
#define jsimd_h2v2_fancy_upsample jSH2V2FUp
#define jsimd_h2v1_fancy_upsample jSH2V1FUp
#define jsimd_can_h2v2_merged_upsample jSCanH2V2MUp
#define jsimd_can_h2v1_merged_upsample jSCanH2V1MUp
#define jsimd_h2v2_merged_upsample jSH2V2MUp
#define jsimd_h2v1_merged_upsample jSH2V1MUp
#endif /* NEED_SHORT_EXTERNAL_NAMES */
EXTERN(int) jsimd_can_rgb_ycc JPP((void));
EXTERN(int) jsimd_can_ycc_rgb JPP((void));
EXTERN(void) jsimd_rgb_ycc_convert
JPP((j_compress_ptr cinfo,
JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
JDIMENSION output_row, int num_rows));
EXTERN(void) jsimd_ycc_rgb_convert
JPP((j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION input_row,
JSAMPARRAY output_buf, int num_rows));
EXTERN(int) jsimd_can_h2v2_downsample JPP((void));
EXTERN(int) jsimd_can_h2v1_downsample JPP((void));
EXTERN(void) jsimd_h2v2_downsample
JPP((j_compress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY output_data));
EXTERN(void) jsimd_h2v1_downsample
JPP((j_compress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY output_data));
EXTERN(int) jsimd_can_h2v2_upsample JPP((void));
EXTERN(int) jsimd_can_h2v1_upsample JPP((void));
EXTERN(void) jsimd_h2v2_upsample
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
EXTERN(void) jsimd_h2v1_upsample
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
EXTERN(int) jsimd_can_h2v2_fancy_upsample JPP((void));
EXTERN(int) jsimd_can_h2v1_fancy_upsample JPP((void));
EXTERN(void) jsimd_h2v2_fancy_upsample
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
EXTERN(void) jsimd_h2v1_fancy_upsample
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
EXTERN(int) jsimd_can_h2v2_merged_upsample JPP((void));
EXTERN(int) jsimd_can_h2v1_merged_upsample JPP((void));
EXTERN(void) jsimd_h2v2_merged_upsample
JPP((j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
JSAMPARRAY output_buf));
EXTERN(void) jsimd_h2v1_merged_upsample
JPP((j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
JSAMPARRAY output_buf));

Some files were not shown because too many files have changed in this diff Show More