Compare commits

...

156 Commits

Author SHA1 Message Date
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
Thomas G. Lane
5ead57a34a The Independent JPEG Group's JPEG software v6b 2015-07-27 13:43:00 -05:00
Thomas G. Lane
489583f516 The Independent JPEG Group's JPEG software v6a 2015-07-29 15:32:35 -05: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
241 changed files with 37220 additions and 10174 deletions

306
BUILDING.txt Normal file
View File

@@ -0,0 +1,306 @@
*******************************************************************************
** Building on Unix Platforms, Cygwin, and MinGW
*******************************************************************************
==================
Build Requirements
==================
-- autoconf 2.56 or later
* If using MinGW, this can be obtained by installing the MSYS DTK
-- automake 1.7 or later
* If using MinGW, this can be obtained by installing the MSYS DTK
-- libtool 1.4 or later
* If using MinGW, this can be obtained by installing the MSYS DTK
-- 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 (10.6 "Snow
Leopard" or later.) This can be obtained from MacPorts
(http://www.macports.org/).
The NASM 2.05 RPMs do not work on older Linux systems, such as 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
======================
Building libjpeg-turbo
======================
The following procedure will build libjpeg-turbo on Linux, 32-bit OS X, and
Solaris/x86 systems (on Solaris, this generates a 32-bit library. See below
for 64-bit build instructions.)
cd libjpeg-turbo
autoreconf -fiv
sh ./configure
make
NOTE: Running autoreconf 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.62.0.0 (Linux, Solaris)
libjpeg.62.dylib (OS X)
libjpeg-62.dll (MinGW)
cygjpeg-62.dll (Cygwin)
Shared library for libjpeg-turbo
libjpeg.so (Linux, Solaris)
libjpeg.dylib (OS X)
libjpeg.dll.a (Cygwin, MinGW)
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
libturbojpeg.dll (MinGW)
cygturbojpeg.dll (Cygwin)
Shared library for TurboJPEG/OSS
libturbojpeg.dll.a (Cygwin, MinGW)
Development stub for TurboJPEG/OSS shared library
========================
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'
to the configure command line.
64-bit Library Build on 64-bit OS/X
-----------------------------------
Add
--host x86_64-apple-darwin10.0.0 NASM=/opt/local/bin/nasm
to the configure command line. NASM 2.07 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.
32-bit Backward-Compatible Library Build on 64-bit 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.
MinGW Build on Cygwin
---------------------
Add
--host mingw32
to the configure command line. This will produce libraries which do not
depend on cygwin1.dll or other Cygwin DLL's.
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.
*******************************************************************************
** Building on Windows (Visual C++)
*******************************************************************************
==================
Build Requirements
==================
-- GNU Make v3.7 or later
* Can be found in MSYS (http://www.mingw.org/download.shtml) or
Cygwin (http://www.cygwin.com/)
-- Windows SDK for Windows Server 2008 and .NET Framework 3.5 (or a later
version)
http://msdn.microsoft.com/en-us/windows/dd146047.aspx
* The Windows SDK includes both 32-bit and 64-bit Visual C++ compilers and
everything necessary to build libjpeg-turbo. If you do not already have
Visual C++ installed, then this is the recommended solution. Also tested
with Microsoft Visual C++ 2008 Express Edition (both are free downloads.)
* Add the compiler and SDK binary directories (for instance,
c:\Program Files\Microsoft Visual Studio 9.0\VC\BIN;
c:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE;
c:\Program Files\Microsoft SDKs\Windows\v6.1\bin)
to the system or user PATH environment variable prior to building
libjpeg-turbo.
* Add the compiler and SDK include directories (for instance,
c:\Program Files\Microsoft Visual Studio 9.0\VC\INCLUDE;
c:\Program Files\Microsoft SDKs\Windows\v6.1\include)
to the system or user INCLUDE environment variable prior to building
libjpeg-turbo.
* Add the compiler library directory (for instance,
c:\Program Files\Microsoft Visual Studio 9.0\VC\LIB;
c:\Program Files\Microsoft SDKs\Windows\v6.1\lib)
to the system or user LIB environment variable prior to building
libjpeg-turbo.
-- NASM (http://www.nasm.us/) 0.98 or later
======================
Building libjpeg-turbo
======================
cd libjpeg-turbo
make -f win/Makefile
This will generate the following files under libjpeg-turbo\windows\:
jpeg-static.lib Static link library for libjpeg-turbo
jpeg62.dll Shared library for libjpeg-turbo
jpeg.lib Development stub for libjpeg-turbo shared library
turbojpeg-static.lib Static link library for TurboJPEG/OSS
turbojpeg.dll Shared library for TurboJPEG/OSS
turbojpeg.lib Development stub for TurboJPEG/OSS shared library
#If a 64-bit Windows platform is detected, then the build system will attempt
#to build a 64-bit version of libjpeg-turbo. You can override this by running
#
# make -f win/Makefile WIN64=no
NOTE: For unknown reasons, Win64 support doesn't work yet, so at the moment,
you have to run 'make -f win/Makefile WIN64=yes' to get a 64-bit build on
64-bit Windows. The paragraph above will apply once Win64 support is working.
*******************************************************************************
** Creating Release Packages
*******************************************************************************
The following commands can be used to create various types of release packages:
make rpm
Create RedHat-style binary RPM package. Requires RPM v4 or later.
make srpm
This runs 'make dist' to create a pristine source tarball, then creates a
RedHat-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
On 64-bit OS X (10.6 "Snow Leopard" or later), this creates a version of the
Macintosh package/disk image which contains universal i386/x86-64 binaries.
The 32-bit fork of these binaries is backward compatible with OS X 10.4 and
later, whereas the 64-bit fork is compatible with OS X 10.6 and later. OS X
10.4 compatibility SDK required.
make nsi
When using MinGW, this creates a Win32 installer for the GCC version of the
libjpeg-turbo SDK. This requires the Nullsoft Install System
(http://nsis.sourceforge.net/.) makensis.exe should be in your PATH.
make -f win/Makefile dist
This creates a Win32 installer for the Visual C++ version of the
libjpeg-turbo SDK. This requires the Nullsoft Install System
(http://nsis.sourceforge.net/.) makensis.exe should be in your PATH.

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.

171
Makefile.am Normal file
View File

@@ -0,0 +1,171 @@
lib_LTLIBRARIES = libjpeg.la libturbojpeg.la
libjpeg_la_LDFLAGS = -version-number 62:0:0 -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
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
libturbojpeg_la_SOURCES = $(libjpeg_la_SOURCES) turbojpegl.c turbojpeg.h \
turbojpeg-mapfile
if VERSION_SCRIPT
libturbojpeg_la_LDFLAGS += $(VERSION_SCRIPT_FLAG)$(srcdir)/turbojpeg-mapfile
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
noinst_PROGRAMS = jpgtest jpegut cjpeg djpeg jpegtran rdjpgcom wrjpgcom
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
DISTMANS= cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 wrjpgcom.1
DOCS= README install.doc usage.doc wizard.doc example.c libjpeg.doc \
structure.doc coderules.doc filelist.doc jconfig.doc change.log \
README-turbo.txt rdrle.c wrrle.c LICENSE.txt LGPL.txt BUILDING.txt
TESTFILES= testorig.jpg testorig.ppm testimg.bmp testimgflt.jpg \
testimgfst.jpg testimgint.jpg testimgp.jpg testimgfst.ppm testimgint.ppm
EXTRA_DIST = win release $(DOCS) $(DISTMANS) $(TESTFILES)
dist-hook:
rm -rf `find $(distdir) -name .svn`
test: testclean cjpeg djpeg jpegtran jpegut
./jpegut
./cjpeg -dct int -outfile testoutint.jpg $(srcdir)/testorig.ppm
./cjpeg -dct fast -opt -outfile testoutfst.jpg $(srcdir)/testorig.ppm
./cjpeg -dct float -outfile testoutflt.jpg $(srcdir)/testorig.ppm
cmp $(srcdir)/testimgint.jpg testoutint.jpg
cmp $(srcdir)/testimgfst.jpg testoutfst.jpg
cmp $(srcdir)/testimgflt.jpg testoutflt.jpg
./djpeg -dct int -fast -ppm -outfile testoutint.ppm $(srcdir)/testorig.jpg
./djpeg -dct fast -ppm -outfile testoutfst.ppm $(srcdir)/testorig.jpg
./djpeg -dct float -ppm -outfile testoutflt.ppm $(srcdir)/testorig.jpg
cmp $(srcdir)/testimgint.ppm testoutint.ppm
cmp $(srcdir)/testimgfst.ppm testoutfst.ppm
cmp $(srcdir)/testorig.ppm testoutflt.ppm
./djpeg -dct int -bmp -colors 256 -outfile testout.bmp $(srcdir)/testorig.jpg
cmp $(srcdir)/testimg.bmp testout.bmp
./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
testclean:
$(RM) testout*
$(RM) *_GRAYQ[0-9]*.bmp
$(RM) *_GRAYQ[0-9]*.ppm
$(RM) *_GRAYQ[0-9]*.jpg
$(RM) *_420Q[0-9]*.bmp
$(RM) *_420Q[0-9]*.ppm
$(RM) *_420Q[0-9]*.jpg
$(RM) *_422Q[0-9]*.bmp
$(RM) *_422Q[0-9]*.ppm
$(RM) *_422Q[0-9]*.jpg
$(RM) *_444Q[0-9]*.bmp
$(RM) *_444Q[0-9]*.ppm
$(RM) *_444Q[0-9]*.jpg
rpm: all
sh $(srcdir)/release/makerpm ${PACKAGE_NAME} ${VERSION} ${BUILD} \
${RPMARCH} ${srcdir}
srpm: dist-gzip
sh $(srcdir)/release/makesrpm ${PACKAGE_NAME} ${VERSION} ${BUILD} ${srcdir}
deb: all
sh $(srcdir)/release/makedpkg ${PACKAGE_NAME} ${VERSION} ${BUILD} \
${DEBARCH} ${srcdir}
if X86_64
udmg: all
sh $(srcdir)/release/makemacpkg ${PACKAGE_NAME} ${VERSION} ${BUILD} \
${srcdir} universal
endif
dmg: all
sh $(srcdir)/release/makemacpkg ${PACKAGE_NAME} ${VERSION} ${BUILD} ${srcdir}
if X86_64
sunpkg: all
sh $(srcdir)/release/makesunpkg ${PACKAGE_NAME} ${VERSION} ${BUILD} \
${DEBARCH} ${srcdir} $(CC) $(CXX) combined
else
sunpkg: all
sh $(srcdir)/release/makesunpkg ${PACKAGE_NAME} ${VERSION} ${BUILD} \
${DEBARCH} ${srcdir} $(CC) $(CXX)
endif
nsi: all
makensis -nocd -DVERSION=$(VERSION) -DAPPNAME=libjpeg-turbo-gcc \
-DWLIBDIR=.libs -DWSRCDIR=$(srcdir) -DWBLDDIR=. -DWHDRDIR=. \
-DPLATFORM="GCC" -DGCC $(srcdir)/release/libjpeg-turbo.nsi

175
README
View File

@@ -1,8 +1,15 @@
libjpeg-turbo note: This is the legacy document from the original libjpeg v6b
release, which is included for reference. The Internet addresses given below
are likely non-functional. For more information about the libjpeg project,
please see http://www.ijg.org. For more information about libjpeg-turbo,
please see http://libjpeg-turbo.virtualgl.org.
The Independent JPEG Group's JPEG software The Independent JPEG Group's JPEG software
========================================== ==========================================
README for release 6 of 2-Aug-95 README for release 6b of 27-Mar-1998
================================ ====================================
This distribution contains the sixth public release of the Independent JPEG This distribution contains the sixth public release of the Independent JPEG
Group's free JPEG software. You are welcome to redistribute this software and Group's free JPEG software. You are welcome to redistribute this software and
@@ -13,9 +20,10 @@ 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 our electronic mailing list. Mailing list members are notified of updates
and have a chance to participate in technical discussions, etc. and have a chance to participate in technical discussions, etc.
This software is the work of Tom Lane, Philip Gladstone, Luis Ortiz, Jim This software is the work of Tom Lane, Philip Gladstone, Jim Boucher,
Boucher, Lee Crocker, Julian Minguillon, George Phillips, Davide Rossi, Lee Crocker, Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi,
Ge' Weijers, and other members of the Independent JPEG Group. Guido Vollbeding, Ge' Weijers, and other members of the Independent JPEG
Group.
IJG is not affiliated with the official ISO JPEG standards committee. IJG is not affiliated with the official ISO JPEG standards committee.
@@ -126,7 +134,7 @@ with respect to this software, its quality, accuracy, merchantability, or
fitness for a particular purpose. This software is provided "AS IS", and you, 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. its user, assume the entire risk as to its quality and accuracy.
This software is copyright (C) 1991, 1992, 1993, 1994, 1995, Thomas G. Lane. This software is copyright (C) 1991-1998, Thomas G. Lane.
All Rights Reserved except as specified below. All Rights Reserved except as specified below.
Permission is hereby granted to use, copy, modify, and distribute this Permission is hereby granted to use, copy, modify, and distribute this
@@ -166,8 +174,11 @@ 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 of any program generated from the IJG code, this does not limit you more than
the foregoing paragraphs do. the foregoing paragraphs do.
The configuration script "configure" was produced with GNU Autoconf. It The Unix configuration script "configure" was produced with GNU Autoconf.
is copyright by the Free Software Foundation but is freely distributable. It is copyright by the Free Software Foundation but is freely distributable.
The same holds for its supporting scripts (config.guess, config.sub,
ltconfig, ltmain.sh). Another support script, install-sh, is copyright
by M.I.T. but is also freely distributable.
It appears that the arithmetic coding option of the JPEG spec is covered by 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 patents owned by IBM, AT&T, and Mitsubishi. Hence arithmetic coding cannot
@@ -178,13 +189,12 @@ 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 So far as we are aware, there are no patent restrictions on the remaining
code. code.
WARNING: Unisys has begun to enforce their patent on LZW compression against The IJG distribution formerly included code to read and write GIF files.
GIF encoders and decoders. You will need a license from Unisys to use the To avoid entanglement with the Unisys LZW patent, GIF reading support has
included rdgif.c or wrgif.c files in a commercial or shareware application. been removed altogether, and the GIF writer has been simplified to produce
At this time, Unisys is not enforcing their patent against freeware, so "uncompressed GIFs". This technique does not use the LZW algorithm; the
distribution of this package remains legal. However, we intend to remove resulting GIF files are larger than usual, but are readable by all standard
GIF support from the IJG package as soon as a suitable replacement format GIF decoders.
becomes reasonably popular.
We are required to state that We are required to state that
"The Graphics Interchange Format(c) is the Copyright property of "The Graphics Interchange Format(c) is the Copyright property of
@@ -203,21 +213,21 @@ The best short technical introduction to the JPEG compression algorithm is
Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44. Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44.
(Adjacent articles in that issue discuss MPEG motion picture compression, (Adjacent articles in that issue discuss MPEG motion picture compression,
applications of JPEG, and related topics.) If you don't have the CACM issue 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 handy, a PostScript file containing a revised version of Wallace's article is
is available at ftp.uu.net, graphics/jpeg/wallace.ps.gz. The file (actually available at ftp://ftp.uu.net/graphics/jpeg/wallace.ps.gz. The file (actually
a preprint for an article that appeared in IEEE Trans. Consumer Electronics) a preprint for an article that appeared in IEEE Trans. Consumer Electronics)
omits the sample images that appeared in CACM, but it includes corrections omits the sample images that appeared in CACM, but it includes corrections
and some added material. Note: the Wallace article is copyright ACM and and some added material. Note: the Wallace article is copyright ACM and IEEE,
IEEE, and it may not be used for commercial purposes. and it may not be used for commercial purposes.
A somewhat less technical, more leisurely introduction to JPEG can be found in 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 "The Data Compression Book" by Mark Nelson and Jean-loup Gailly, published by
City, CA), 1991, ISBN 1-55851-216-0. This book provides good explanations and M&T Books (New York), 2nd ed. 1996, ISBN 1-55851-434-1. This book provides
example C code for a multitude of compression methods including JPEG. It is good explanations and example C code for a multitude of compression methods
an excellent source if you are comfortable reading C code but don't know much including JPEG. It is an excellent source if you are comfortable reading C
about data compression in general. The book's JPEG sample code is far from code but don't know much about data compression in general. The book's JPEG
industrial-strength, but when you are ready to look at a full implementation, sample code is far from industrial-strength, but when you are ready to look
you've got one here... at a full implementation, you've got one here...
The best full description of JPEG is the textbook "JPEG Still Image Data The best full description of JPEG is the textbook "JPEG Still Image Data
Compression Standard" by William B. Pennebaker and Joan L. Mitchell, published Compression Standard" by William B. Pennebaker and Joan L. Mitchell, published
@@ -227,23 +237,24 @@ and draft DIS 10918-2). This is by far the most complete exposition of JPEG
in existence, and we highly recommend it. in existence, and we highly recommend it.
The JPEG standard itself is not available electronically; you must order a The JPEG standard itself is not available electronically; you must order a
paper copy through ISO. (Unless you feel a need to own a certified official paper copy through ISO or ITU. (Unless you feel a need to own a certified
copy, we recommend buying the Pennebaker and Mitchell book instead; it's much official copy, we recommend buying the Pennebaker and Mitchell book instead;
cheaper and includes a great deal of useful explanatory material.) In the US, it's much cheaper and includes a great deal of useful explanatory material.)
copies of the standard may be ordered from ANSI Sales at (212) 642-4900, or In the USA, copies of the standard may be ordered from ANSI Sales at (212)
from Global Engineering Documents at (800) 854-7179. (ANSI doesn't take 642-4900, or from Global Engineering Documents at (800) 854-7179. (ANSI
credit card orders, but Global does.) It's not cheap: as of 1992, ANSI was doesn't take credit card orders, but Global does.) It's not cheap: as of
charging $95 for Part 1 and $47 for Part 2, plus 7% shipping/handling. The 1992, ANSI was charging $95 for Part 1 and $47 for Part 2, plus 7%
standard is divided into two parts, Part 1 being the actual specification, shipping/handling. The standard is divided into two parts, Part 1 being the
while Part 2 covers compliance testing methods. Part 1 is titled "Digital actual specification, while Part 2 covers compliance testing methods. Part 1
Compression and Coding of Continuous-tone Still Images, Part 1: Requirements is titled "Digital Compression and Coding of Continuous-tone Still Images,
and guidelines" and has document number ISO/IEC IS 10918-1. Part 2 is titled Part 1: Requirements and guidelines" and has document numbers ISO/IEC IS
"Digital Compression and Coding of Continuous-tone Still Images, Part 2: 10918-1, ITU-T T.81. Part 2 is titled "Digital Compression and Coding of
Compliance testing" and has document number ISO/IEC IS 10918-2. 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 Part 3, a new ISO Some extensions to the original JPEG standard are defined in JPEG Part 3,
document. Part 3 is undergoing ISO balloting and is expected to be approved a newer ISO standard numbered ISO/IEC IS 10918-3 and ITU-T T.84. IJG
by the end of 1995. IJG currently does not support any Part 3 extensions. currently does not support any Part 3 extensions.
The JPEG standard does not specify all details of an interchangeable file The JPEG standard does not specify all details of an interchangeable file
format. For the omitted details we follow the "JFIF" conventions, revision format. For the omitted details we follow the "JFIF" conventions, revision
@@ -253,24 +264,22 @@ format. For the omitted details we follow the "JFIF" conventions, revision
1778 McCarthy Blvd. 1778 McCarthy Blvd.
Milpitas, CA 95035 Milpitas, CA 95035
phone (408) 944-6300, fax (408) 944-6314 phone (408) 944-6300, fax (408) 944-6314
A PostScript version of this document is available at ftp.uu.net, file A PostScript version of this document is available by FTP at
graphics/jpeg/jfif.ps.gz. It can also be obtained by e-mail from the C-Cube ftp://ftp.uu.net/graphics/jpeg/jfif.ps.gz. There is also a plain text
mail server, netlib@c3.pla.ca.us. Send the message "send jfif_ps from jpeg" version at ftp://ftp.uu.net/graphics/jpeg/jfif.txt.gz, but it is missing
to the server to obtain the JFIF document; send the message "help" if you have the figures.
trouble.
The TIFF 6.0 file format specification can be obtained by FTP from sgi.com The TIFF 6.0 file format specification can be obtained by FTP from
(192.48.153.1), file graphics/tiff/TIFF6.ps.Z; or you can order a printed ftp://ftp.sgi.com/graphics/tiff/TIFF6.ps.gz. The JPEG incorporation scheme
copy from Aldus Corp. at (206) 628-6593. The JPEG incorporation scheme
found in the TIFF 6.0 spec of 3-June-92 has a number of serious problems. 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). 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 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 (Compression tag 7). Copies of this Note can be obtained from ftp.sgi.com or
from ftp.uu.net:/graphics/jpeg/. It is expected that the next revision of from ftp://ftp.uu.net/graphics/jpeg/. It is expected that the next revision
the TIFF spec will replace the 6.0 JPEG design with the Note's design. 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 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 uses our library to implement TIFF/JPEG per the Note. libtiff is available
from sgi.com:/graphics/tiff/. from ftp://ftp.sgi.com/graphics/tiff/.
ARCHIVE LOCATIONS ARCHIVE LOCATIONS
@@ -279,28 +288,27 @@ ARCHIVE LOCATIONS
The "official" archive site for this software is ftp.uu.net (Internet 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 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 there in directory graphics/jpeg. This particular version will be archived
as graphics/jpeg/jpegsrc.v6.tar.gz. If you are on the Internet, you as ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz. If you don't have
can retrieve files from ftp.uu.net by standard anonymous FTP. If you don't direct Internet access, UUNET's archives are also available via UUCP; contact
have FTP access, UUNET's archives are also available via UUCP; contact
help@uunet.uu.net for information on retrieving files that way. help@uunet.uu.net for information on retrieving files that way.
Numerous Internet sites maintain copies of the UUNET files; in particular, Numerous Internet sites maintain copies of the UUNET files. However, only
you can probably find a copy at any site that archives comp.sources.misc ftp.uu.net is guaranteed to have the latest official version.
submissions. 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 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 the SimTel archives (ftp://ftp.simtel.net/pub/simtelnet/msdos/graphics/), or
in the GRAPHSUPPORT forum (GO GRAPHSUP), library 12 "JPEG Tools". Again, on CompuServe in the Graphics Support forum (GO CIS:GRAPHSUP), library 12
these versions may sometimes lag behind the ftp.uu.net release. "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 The JPEG FAQ (Frequently Asked Questions) article is a useful source of
general information about JPEG. It is updated constantly and therefore is general information about JPEG. It is updated constantly and therefore is
not included in this distribution. The FAQ is posted every two weeks to not included in this distribution. The FAQ is posted every two weeks to
Usenet newsgroups comp.graphics, news.answers, and other groups. You can Usenet newsgroups comp.graphics.misc, news.answers, and other groups.
always obtain the latest version from the news.answers archive at It is available on the World Wide Web at http://www.faqs.org/faqs/jpeg-faq/
rtfm.mit.edu. By FTP, fetch /pub/usenet/news.answers/jpeg-faq/part1 and and other news.answers archive sites, including the official news.answers
.../part2. If you don't have FTP, send e-mail to mail-server@rtfm.mit.edu 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 with body
send usenet/news.answers/jpeg-faq/part1 send usenet/news.answers/jpeg-faq/part1
send usenet/news.answers/jpeg-faq/part2 send usenet/news.answers/jpeg-faq/part2
@@ -315,21 +323,20 @@ some of the more popular free and shareware viewers, and tells where to
obtain them on Internet. obtain them on Internet.
If you are on a Unix machine, we highly recommend Jef Poskanzer's free 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 PBMPLUS software, which provides many useful operations on PPM-format image
image files. In particular, it can convert PPM images to and from a wide files. In particular, it can convert PPM images to and from a wide range of
range of other formats. You can obtain this package by FTP from ftp.x.org other formats, thus making cjpeg/djpeg considerably more useful. The latest
(contrib/pbmplus*.tar.Z) or ftp.ee.lbl.gov (pbmplus*.tar.Z). There is also version is distributed by the NetPBM group, and is available from numerous
a newer update of this package called NETPBM, available from sites, notably ftp://wuarchive.wustl.edu/graphics/graphics/packages/NetPBM/.
wuarchive.wustl.edu under directory /graphics/graphics/packages/NetPBM/. Unfortunately PBMPLUS/NETPBM is not nearly as portable as the IJG software is;
Unfortunately PBMPLUS/NETPBM is not nearly as portable as the IJG software you are likely to have difficulty making it work on any non-Unix machine.
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, 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 available from ftp://havefun.stanford.edu/pub/jpeg/. This program
is designed for research and experimentation rather than production use; 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 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, is easier to read and modify. Also, the PVRG code supports lossless JPEG,
which we do not. which we do not. (On the other hand, it doesn't do progressive JPEG.)
FILE FORMAT WARS FILE FORMAT WARS
@@ -370,14 +377,16 @@ use a proprietary file format!
TO DO TO DO
===== =====
The major thrust for v7 will probably be improvement of visual quality.
The current method for scaling the quantization tables is known not to be
very good at low Q values. We also intend to investigate block boundary
smoothing, "poor man's variable quantization", and other means of improving
quality-vs-file-size performance without sacrificing compatibility.
In future versions, we are considering supporting some of the upcoming JPEG In future versions, we are considering supporting some of the upcoming JPEG
Part 3 extensions --- principally, variable quantization and the SPIFF file Part 3 extensions --- principally, variable quantization and the SPIFF file
format. format.
Tuning the software for better behavior at low quality/high compression As always, speeding things up is of great interest.
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@uunet.uu.net.

196
README-turbo.txt Executable file
View File

@@ -0,0 +1,196 @@
*******************************************************************************
** 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/decoder were borrowed from
VirtualGL, and thus the libjpeg-turbo distribution, as a whole, falls under the
wxWindows Library Licence, Version 3.1. A copy of this license can be found in
this directory under LICENSE.txt. The rest of the source code, apart from
these modifications, falls under a less restrictive license (see README.)
*******************************************************************************
** 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/amd64, 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 jpeg62.dll into
c:\libjpeg-turbo\bin, and the PATH environment variable can be modified such
that this directory is searched before any others that might contain
jpeg62.dll. However, if jpeg62.dll also exists in an application's install
directory, then Windows will load the application's version of it first. Thus,
if an application ships with jpeg62.dll, then back up the application's version
of jpeg62.dll and copy c:\libjpeg-turbo\bin\jpeg62.dll into the application's
install directory to accelerate it.
The version of jpeg62.dll distributed in the libjpeg-turbo SDK requires the
Visual C++ 2008 C run time DLL (msvcr90.dll). This library ships with more
recent versions of Windows, but users of older versions 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 distributed version of jpeg62.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 libjpeg.62.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.62.dylib 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 prior) and TurboVNC. 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 contain 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 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 VirtualGL 2.2 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, you can build against libjpeg-turbo instead
of libjpeg by setting
CPATH=/opt/libjpeg-turbo/include
and
LIBRARY_PATH=/opt/libjpeg-turbo/{lib}
({lib} = lib, lib32, lib64, or lib/amd64, as appropriate.)
If using Cygwin, then set
CPATH=/cygdrive/c/libjpeg-turbo-gcc/include
and
LIBRARY_PATH=/cygdrive/c/libjpeg-turbo-gcc/lib
If using MinGW, then set
CPATH=/c/libjpeg-turbo-gcc/include
and
LIBRARY_PATH=/c/libjpeg-turbo-gcc/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\include to your system or user INCLUDE environment variable
and c:\libjpeg-turbo\lib to your system or user LIB environment variable, and
then link against either jpeg.lib (to use jpeg62.dll) 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, BGRA,
RGBA, ABGR, and ARGB 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.

129
acinclude.m4 Normal file
View File

@@ -0,0 +1,129 @@
# 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
objfmt='ELF'
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,19 +0,0 @@
.TH ANSI2KNR 1 "31 December 1990"
.SH NAME
ansi2knr \- convert ANSI C to Kernighan & Ritchie C
.SH SYNOPSIS
.I ansi2knr
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 functions 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. It will recognize a multi-line header if the last character on each line but the last is a left parenthesis or comma. 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
- Macros that tinker with the syntax of the function header.

View File

@@ -1,496 +0,0 @@
/* Copyright (C) 1989, 1991, 1993 Aladdin Enterprises. All rights reserved. */
/* ansi2knr.c */
/* Convert ANSI function declarations to K&R 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 COPYING, 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 COPYING ------------------------------
*/
#include <stdio.h>
#include <ctype.h>
#ifdef BSD
#include <strings.h>
#else
#ifdef VMS
extern int strlen(), strncmp();
#else
#include <string.h>
#endif
#endif
/* 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
/* Usage:
ansi2knr input_file [output_file]
* If no output_file is supplied, output goes to stdout.
* There are no error messages.
*
* ansi2knr recognizes functions 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.
* It will recognize a multi-line header provided that the last character
* of the last line of the header is a right parenthesis,
* and no intervening line ends with a left 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).
* - Macros that tinker with the syntax of the function header.
*/
/* Scanning macros */
#define isidchar(ch) (isalnum(ch) || (ch) == '_')
#define isidfirstchar(ch) (isalpha(ch) || (ch) == '_')
/* Forward references */
char *skipspace();
int writeblanks();
int test1();
int convert1();
/* The main program */
main(argc, argv)
int argc;
char *argv[];
{ FILE *in, *out;
#define bufsize 5000 /* arbitrary size */
char *buf;
char *line;
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 %s\n", argv[2]);
exit(1);
}
}
in = fopen(argv[1], "r");
if ( in == NULL )
{ fprintf(stderr, "Cannot open %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 )
{ switch ( test1(buf) )
{
case 1: /* a function */
convert1(buf, out);
break;
case -1: /* maybe the start of a function */
line = buf + strlen(buf);
if ( line != buf + (bufsize - 1) ) /* overflow check */
continue;
/* falls through */
default: /* not a function */
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 ( isspace(*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.
*/
int
writeblanks(start, end)
char *start;
char *end;
{ char *p;
for ( p = start; p < end; p++ ) *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;
* -1 - may be the beginning of a function definition,
* append another line and look again.
*/
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 = 1; break;
case '{':
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;
}
int
convert1(buf, out)
char *buf;
FILE *out;
{ char *endfn;
register char *p;
char **breaks;
unsigned num_breaks = 2; /* for testing */
char **btop;
char **bp;
char **ap;
/* 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 *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 '(': level++; break;
case ')': if ( --level < 0 ) end = p; break;
case '/': p = skipspace(p, 1) - 1; break;
default: ;
}
}
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] == '.' )
{ 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 */
p = buf;
while ( p != endfn ) putc(*p, out), p++;
/* Put out the declaration */
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] = ';';
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,7 @@
/* /*
* cderror.h * cderror.h
* *
* Copyright (C) 1994, Thomas G. Lane. * Copyright (C) 1994-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -72,7 +72,7 @@ JMESSAGE(JWRN_GIF_NOMOREDATA, "Ran out of GIF bits")
#ifdef PPM_SUPPORTED #ifdef PPM_SUPPORTED
JMESSAGE(JERR_PPM_COLORSPACE, "PPM output must be grayscale or RGB") JMESSAGE(JERR_PPM_COLORSPACE, "PPM output must be grayscale or RGB")
JMESSAGE(JERR_PPM_NONNUMERIC, "Nonnumeric data in PPM file") 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, "%ux%u PGM image")
JMESSAGE(JTRC_PGM_TEXT, "%ux%u text PGM image") JMESSAGE(JTRC_PGM_TEXT, "%ux%u text PGM image")
JMESSAGE(JTRC_PPM, "%ux%u PPM image") JMESSAGE(JTRC_PPM, "%ux%u PPM image")

View File

@@ -1,7 +1,7 @@
/* /*
* cdjpeg.c * cdjpeg.c
* *
* Copyright (C) 1991-1995, Thomas G. Lane. * Copyright (C) 1991-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -31,7 +31,7 @@
static j_common_ptr sig_cinfo; static j_common_ptr sig_cinfo;
GLOBAL void /* must be global for Manx C */ void /* must be global for Manx C */
signal_catcher (int signum) signal_catcher (int signum)
{ {
if (sig_cinfo != NULL) { if (sig_cinfo != NULL) {
@@ -43,11 +43,13 @@ signal_catcher (int signum)
} }
GLOBAL void GLOBAL(void)
enable_signal_catcher (j_common_ptr cinfo) enable_signal_catcher (j_common_ptr cinfo)
{ {
sig_cinfo = cinfo; sig_cinfo = cinfo;
#ifdef SIGINT /* not all systems have SIGINT */
signal(SIGINT, signal_catcher); signal(SIGINT, signal_catcher);
#endif
#ifdef SIGTERM /* not all systems have SIGTERM */ #ifdef SIGTERM /* not all systems have SIGTERM */
signal(SIGTERM, signal_catcher); signal(SIGTERM, signal_catcher);
#endif #endif
@@ -62,7 +64,7 @@ enable_signal_catcher (j_common_ptr cinfo)
#ifdef PROGRESS_REPORT #ifdef PROGRESS_REPORT
METHODDEF void METHODDEF(void)
progress_monitor (j_common_ptr cinfo) progress_monitor (j_common_ptr cinfo)
{ {
cd_progress_ptr prog = (cd_progress_ptr) cinfo->progress; cd_progress_ptr prog = (cd_progress_ptr) cinfo->progress;
@@ -83,7 +85,7 @@ progress_monitor (j_common_ptr cinfo)
} }
GLOBAL void GLOBAL(void)
start_progress_monitor (j_common_ptr cinfo, cd_progress_ptr progress) start_progress_monitor (j_common_ptr cinfo, cd_progress_ptr progress)
{ {
/* Enable progress display, unless trace output is on */ /* Enable progress display, unless trace output is on */
@@ -97,7 +99,7 @@ start_progress_monitor (j_common_ptr cinfo, cd_progress_ptr progress)
} }
GLOBAL void GLOBAL(void)
end_progress_monitor (j_common_ptr cinfo) end_progress_monitor (j_common_ptr cinfo)
{ {
/* Clear away progress display */ /* Clear away progress display */
@@ -116,7 +118,7 @@ end_progress_monitor (j_common_ptr cinfo)
* minchars is length of minimum legal abbreviation. * minchars is length of minimum legal abbreviation.
*/ */
GLOBAL boolean GLOBAL(boolean)
keymatch (char * arg, const char * keyword, int minchars) keymatch (char * arg, const char * keyword, int minchars)
{ {
register int ca, ck; register int ca, ck;
@@ -143,7 +145,7 @@ keymatch (char * arg, const char * keyword, int minchars)
* Non-Unix systems often require some hacking to get out of text mode. * Non-Unix systems often require some hacking to get out of text mode.
*/ */
GLOBAL FILE * GLOBAL(FILE *)
read_stdin (void) read_stdin (void)
{ {
FILE * input_file = stdin; FILE * input_file = stdin;
@@ -161,7 +163,7 @@ read_stdin (void)
} }
GLOBAL FILE * GLOBAL(FILE *)
write_stdout (void) write_stdout (void)
{ {
FILE * output_file = stdout; FILE * output_file = stdout;

View File

@@ -1,7 +1,7 @@
/* /*
* cdjpeg.h * cdjpeg.h
* *
* Copyright (C) 1994-1995, Thomas G. Lane. * Copyright (C) 1994-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -116,39 +116,39 @@ typedef struct cdjpeg_progress_mgr * cd_progress_ptr;
/* Module selection routines for I/O modules. */ /* Module selection routines for I/O modules. */
EXTERN cjpeg_source_ptr jinit_read_bmp JPP((j_compress_ptr cinfo)); EXTERN(cjpeg_source_ptr) jinit_read_bmp JPP((j_compress_ptr cinfo));
EXTERN djpeg_dest_ptr jinit_write_bmp JPP((j_decompress_ptr cinfo, EXTERN(djpeg_dest_ptr) jinit_write_bmp JPP((j_decompress_ptr cinfo,
boolean is_os2)); boolean is_os2));
EXTERN cjpeg_source_ptr jinit_read_gif JPP((j_compress_ptr cinfo)); EXTERN(cjpeg_source_ptr) jinit_read_gif JPP((j_compress_ptr cinfo));
EXTERN djpeg_dest_ptr jinit_write_gif JPP((j_decompress_ptr cinfo)); EXTERN(djpeg_dest_ptr) jinit_write_gif JPP((j_decompress_ptr cinfo));
EXTERN cjpeg_source_ptr jinit_read_ppm JPP((j_compress_ptr cinfo)); EXTERN(cjpeg_source_ptr) jinit_read_ppm JPP((j_compress_ptr cinfo));
EXTERN djpeg_dest_ptr jinit_write_ppm JPP((j_decompress_ptr cinfo)); EXTERN(djpeg_dest_ptr) jinit_write_ppm JPP((j_decompress_ptr cinfo));
EXTERN cjpeg_source_ptr jinit_read_rle JPP((j_compress_ptr cinfo)); EXTERN(cjpeg_source_ptr) jinit_read_rle JPP((j_compress_ptr cinfo));
EXTERN djpeg_dest_ptr jinit_write_rle JPP((j_decompress_ptr cinfo)); EXTERN(djpeg_dest_ptr) jinit_write_rle JPP((j_decompress_ptr cinfo));
EXTERN cjpeg_source_ptr jinit_read_targa JPP((j_compress_ptr cinfo)); EXTERN(cjpeg_source_ptr) jinit_read_targa JPP((j_compress_ptr cinfo));
EXTERN djpeg_dest_ptr jinit_write_targa JPP((j_decompress_ptr cinfo)); EXTERN(djpeg_dest_ptr) jinit_write_targa JPP((j_decompress_ptr cinfo));
/* cjpeg support routines (in rdswitch.c) */ /* cjpeg support routines (in rdswitch.c) */
EXTERN boolean read_quant_tables JPP((j_compress_ptr cinfo, char * filename, EXTERN(boolean) read_quant_tables JPP((j_compress_ptr cinfo, char * filename,
int scale_factor, boolean force_baseline)); int scale_factor, boolean force_baseline));
EXTERN boolean read_scan_script JPP((j_compress_ptr cinfo, char * filename)); EXTERN(boolean) read_scan_script JPP((j_compress_ptr cinfo, char * filename));
EXTERN boolean set_quant_slots JPP((j_compress_ptr cinfo, char *arg)); EXTERN(boolean) set_quant_slots JPP((j_compress_ptr cinfo, char *arg));
EXTERN boolean set_sample_factors JPP((j_compress_ptr cinfo, char *arg)); EXTERN(boolean) set_sample_factors JPP((j_compress_ptr cinfo, char *arg));
/* djpeg support routines (in rdcolmap.c) */ /* djpeg support routines (in rdcolmap.c) */
EXTERN void read_color_map JPP((j_decompress_ptr cinfo, FILE * infile)); EXTERN(void) read_color_map JPP((j_decompress_ptr cinfo, FILE * infile));
/* common support routines (in cdjpeg.c) */ /* common support routines (in cdjpeg.c) */
EXTERN void enable_signal_catcher JPP((j_common_ptr cinfo)); EXTERN(void) enable_signal_catcher JPP((j_common_ptr cinfo));
EXTERN void start_progress_monitor JPP((j_common_ptr cinfo, EXTERN(void) start_progress_monitor JPP((j_common_ptr cinfo,
cd_progress_ptr progress)); cd_progress_ptr progress));
EXTERN void end_progress_monitor JPP((j_common_ptr cinfo)); EXTERN(void) end_progress_monitor JPP((j_common_ptr cinfo));
EXTERN boolean keymatch JPP((char * arg, const char * keyword, int minchars)); EXTERN(boolean) keymatch JPP((char * arg, const char * keyword, int minchars));
EXTERN FILE * read_stdin JPP((void)); EXTERN(FILE *) read_stdin JPP((void));
EXTERN FILE * write_stdout JPP((void)); EXTERN(FILE *) write_stdout JPP((void));
/* miscellaneous useful macros */ /* miscellaneous useful macros */
@@ -156,9 +156,14 @@ EXTERN FILE * write_stdout JPP((void));
#define READ_BINARY "r" #define READ_BINARY "r"
#define WRITE_BINARY "w" #define WRITE_BINARY "w"
#else #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 READ_BINARY "rb"
#define WRITE_BINARY "wb" #define WRITE_BINARY "wb"
#endif #endif
#endif
#ifndef EXIT_FAILURE /* define exit() codes if not provided */ #ifndef EXIT_FAILURE /* define exit() codes if not provided */
#define EXIT_FAILURE 1 #define EXIT_FAILURE 1

View File

@@ -1,6 +1,111 @@
CHANGE LOG for Independent JPEG Group's JPEG software CHANGE LOG for Independent JPEG Group's JPEG software
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
--------------------
Library initialization sequence modified to detect version mismatches
and struct field packing mismatches between library and calling application.
This change requires applications to be recompiled, but does not require
any application source code change.
All routine declarations changed to the style "GLOBAL(type) name ...",
that is, GLOBAL, LOCAL, METHODDEF, EXTERN are now macros taking the
routine's return type as an argument. This makes it possible to add
Microsoft-style linkage keywords to all the routines by changing just
these macros. Note that any application code that was using these macros
will have to be changed.
DCT coefficient quantization tables are now stored in normal array order
rather than zigzag order. Application code that calls jpeg_add_quant_table,
or otherwise manipulates quantization tables directly, will need to be
changed. If you need to make such code work with either older or newer
versions of the library, a test like "#if JPEG_LIB_VERSION >= 61" is
recommended.
djpeg's trace capability now dumps DQT tables in natural order, not zigzag
order. This allows the trace output to be made into a "-qtables" file
more easily.
New system-dependent memory manager module for use on Apple Macintosh.
Fix bug in cjpeg's -smooth option: last one or two scanlines would be
duplicates of the prior line unless the image height mod 16 was 1 or 2.
Repair minor problems in VMS, BCC, MC6 makefiles.
New configure script based on latest GNU Autoconf.
Correct the list of include files needed by MetroWerks C for ccommand().
Numerous small documentation updates.
Version 6 2-Aug-95 Version 6 2-Aug-95
------------------- -------------------

34
cjpeg.1
View File

@@ -1,4 +1,4 @@
.TH CJPEG 1 "15 June 1995" .TH CJPEG 1 "20 March 1998"
.SH NAME .SH NAME
cjpeg \- compress an image file to a JPEG file cjpeg \- compress an image file to a JPEG file
.SH SYNOPSIS .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 compresses the named image file, or the standard input if no file is
named, and produces a JPEG/JFIF file on the standard output. named, and produces a JPEG/JFIF file on the standard output.
The currently supported input file formats are: PPM (PBMPLUS color 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.) Toolkit format). (RLE is supported only if the URT library is available.)
.SH OPTIONS .SH OPTIONS
All switch names may be abbreviated; for example, All switch names may be abbreviated; for example,
@@ -27,9 +27,9 @@ or
.BR \-gr . .BR \-gr .
Most of the "basic" switches can be abbreviated to as little as one letter. Most of the "basic" switches can be abbreviated to as little as one letter.
Upper and lower case are equivalent (thus Upper and lower case are equivalent (thus
.B \-GIF .B \-BMP
is the same as is the same as
.BR \-gif ). .BR \-bmp ).
British spellings are also accepted (e.g., British spellings are also accepted (e.g.,
.BR \-greyscale ), .BR \-greyscale ),
though for brevity these are not mentioned below. though for brevity these are not mentioned below.
@@ -42,9 +42,9 @@ Scale quantization tables to adjust image quality. Quality is 0 (worst) to
.TP .TP
.B \-grayscale .B \-grayscale
Create monochrome JPEG file from color input. Be sure to use this switch when 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 .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 By saying
.BR \-grayscale , .BR \-grayscale ,
you'll get a smaller JPEG file that takes less time to process. you'll get a smaller JPEG file that takes less time to process.
@@ -180,16 +180,22 @@ for images that will be transmitted across unreliable networks such as Usenet.
The The
.B \-smooth .B \-smooth
option filters the input to eliminate fine-scale noise. This is often useful 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 when converting dithered images to JPEG: a moderate smoothing factor of 10 to
gets rid of dithering patterns in the input file, resulting in a smaller JPEG 50 gets rid of dithering patterns in the input file, resulting in a smaller
file and a better-looking image. Too large a smoothing factor will visibly JPEG file and a better-looking image. Too large a smoothing factor will
blur the image, however. visibly blur the image, however.
.PP .PP
Switches for wizards: Switches for wizards:
.TP .TP
.B \-baseline .B \-baseline
Force a baseline JPEG file to be generated. This clamps quantization values Force baseline-compatible quantization tables to be generated. This clamps
to 8 bits even at low quality settings. 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 .TP
.BI \-qtables " file" .BI \-qtables " file"
Use the quantization tables given in the specified text file. Use the quantization tables given in the specified text file.
@@ -272,6 +278,10 @@ Independent JPEG Group
.SH BUGS .SH BUGS
Arithmetic coding is not supported for legal reasons. Arithmetic coding is not supported for legal reasons.
.PP .PP
GIF input files are no longer supported, to avoid the Unisys LZW patent.
Use a Unisys-licensed program if you need to read a GIF file. (Conversion
of GIF files to JPEG is usually a bad idea anyway.)
.PP
Not all variants of BMP and Targa file formats are supported. Not all variants of BMP and Targa file formats are supported.
.PP .PP
The The

17
cjpeg.c
View File

@@ -1,7 +1,7 @@
/* /*
* cjpeg.c * cjpeg.c
* *
* Copyright (C) 1991-1995, Thomas G. Lane. * Copyright (C) 1991-1998, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -28,7 +28,8 @@
#ifdef USE_CCOMMAND /* command-line reader for Macintosh */ #ifdef USE_CCOMMAND /* command-line reader for Macintosh */
#ifdef __MWERKS__ #ifdef __MWERKS__
#include <SIOUX.h> /* Metrowerks declares it here */ #include <SIOUX.h> /* Metrowerks needs this */
#include <console.h> /* ... and this */
#endif #endif
#ifdef THINK_C #ifdef THINK_C
#include <console.h> /* Think declares it here */ #include <console.h> /* Think declares it here */
@@ -75,7 +76,7 @@ static const char * const cdjpeg_message_table[] = {
static boolean is_targa; /* records user -targa switch */ static boolean is_targa; /* records user -targa switch */
LOCAL cjpeg_source_ptr LOCAL(cjpeg_source_ptr)
select_file_type (j_compress_ptr cinfo, FILE * infile) select_file_type (j_compress_ptr cinfo, FILE * infile)
{ {
int c; int c;
@@ -136,7 +137,7 @@ static const char * progname; /* program name for error messages */
static char * outfilename; /* for -outfile switch */ static char * outfilename; /* for -outfile switch */
LOCAL void LOCAL(void)
usage (void) usage (void)
/* complain about bad command line */ /* complain about bad command line */
{ {
@@ -183,7 +184,7 @@ usage (void)
#ifdef C_ARITH_CODING_SUPPORTED #ifdef C_ARITH_CODING_SUPPORTED
fprintf(stderr, " -arithmetic Use arithmetic coding\n"); fprintf(stderr, " -arithmetic Use arithmetic coding\n");
#endif #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, " -qtables file Use quantization tables given in file\n");
fprintf(stderr, " -qslots N[,...] Set component quantization tables\n"); fprintf(stderr, " -qslots N[,...] Set component quantization tables\n");
fprintf(stderr, " -sample HxV[,...] Set component sampling factors\n"); fprintf(stderr, " -sample HxV[,...] Set component sampling factors\n");
@@ -194,7 +195,7 @@ usage (void)
} }
LOCAL int LOCAL(int)
parse_switches (j_compress_ptr cinfo, int argc, char **argv, parse_switches (j_compress_ptr cinfo, int argc, char **argv,
int last_file_arg_seen, boolean for_real) int last_file_arg_seen, boolean for_real)
/* Parse optional switches. /* Parse optional switches.
@@ -254,7 +255,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
#endif #endif
} else if (keymatch(arg, "baseline", 1)) { } else if (keymatch(arg, "baseline", 1)) {
/* Force baseline output (8-bit quantizer values). */ /* Force baseline-compatible output (8-bit quantizer values). */
force_baseline = TRUE; force_baseline = TRUE;
} else if (keymatch(arg, "dct", 2)) { } else if (keymatch(arg, "dct", 2)) {
@@ -456,7 +457,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
* The main program. * The main program.
*/ */
GLOBAL int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
struct jpeg_compress_struct cinfo; struct jpeg_compress_struct cinfo;

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;
}

View File

@@ -1,6 +1,6 @@
IJG JPEG LIBRARY: CODING RULES IJG JPEG LIBRARY: CODING RULES
Copyright (C) 1991-1994, Thomas G. Lane. Copyright (C) 1991-1996, Thomas G. Lane.
This file is part of the Independent JPEG Group's software. This file is part of the Independent JPEG Group's software.
For conditions of distribution and use, see the accompanying README file. For conditions of distribution and use, see the accompanying README file.
@@ -43,17 +43,17 @@ ansi2knr is not very bright, so it imposes a format requirement on function
declarations: the function name MUST BEGIN IN COLUMN 1. Thus all functions declarations: the function name MUST BEGIN IN COLUMN 1. Thus all functions
should be written in the following style: should be written in the following style:
LOCAL int * LOCAL(int *)
function_name (int a, char *b) function_name (int a, char *b)
{ {
code... code...
} }
Note that each function definition is prefixed with GLOBAL, LOCAL, or Note that each function definition must begin with GLOBAL(type), LOCAL(type),
METHODDEF. These macros expand to "static" or nothing as appropriate. or METHODDEF(type). These macros expand to "static type" or just "type" as
They provide a readable indication of the routine's usage and can readily be appropriate. They provide a readable indication of the routine's usage and
changed for special needs. (For instance, all routines can be made global for can readily be changed for special needs. (For instance, special linkage
use with debuggers or code profilers that require it.) keywords can be inserted for use in Windows DLLs.)
ansi2knr does not transform method declarations (function pointers in ansi2knr does not transform method declarations (function pointers in
structs). We handle these with a macro JMETHOD, defined as structs). We handle these with a macro JMETHOD, defined as
@@ -69,8 +69,8 @@ which is used like this:
}; };
Note the set of parentheses surrounding the parameter list. Note the set of parentheses surrounding the parameter list.
A similar solution is used for external function declarations (see the JPP A similar solution is used for forward and external function declarations
macro). (see the EXTERN and JPP macros).
If the code is to work on non-ANSI compilers, we cannot rely on a prototype If the code is to work on non-ANSI compilers, we cannot rely on a prototype
declaration to coerce actual parameters into the right types. Therefore, use declaration to coerce actual parameters into the right types. Therefore, use

1598
configure vendored

File diff suppressed because it is too large Load Diff

184
configure.ac Normal file
View File

@@ -0,0 +1,184 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.56])
AC_INIT([libjpeg-turbo], [0.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])
# Don't use undefined types
AC_DEFINE([INCOMPLETE_TYPES_BROKEN], 1, [Define if you want use complete types])
# 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
AC_MSG_CHECKING([whether the linker supports version scripts])
VERSION_SCRIPT=no
LDVER=`$LD --help </dev/null 2>&1 | grep "\-\-version-script"`
if test "$LDVER"; then
VERSION_SCRIPT=yes
VERSION_SCRIPT_FLAG=-Wl,--version-script,
AC_MSG_RESULT(yes)
else
LDVER=`$LD --help </dev/null 2>&1 | grep "\-M"`
if test "$LDVER"; then
VERSION_SCRIPT=yes
VERSION_SCRIPT_FLAG=-Wl,-M,
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
fi
fi
AM_CONDITIONAL(VERSION_SCRIPT, test "x$VERSION_SCRIPT" = "xyes")
AC_SUBST(VERSION_SCRIPT_FLAG)
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"])
# 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)
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_ERROR([CPU is not supported])
;;
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"])
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)
# 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([Makefile simd/Makefile])
AC_OUTPUT

19
djpeg.1
View File

@@ -1,4 +1,4 @@
.TH DJPEG 1 "15 June 1995" .TH DJPEG 1 "22 August 1997"
.SH NAME .SH NAME
djpeg \- decompress a JPEG file to an image file djpeg \- decompress a JPEG file to an image file
.SH SYNOPSIS .SH SYNOPSIS
@@ -26,9 +26,9 @@ or
.BR \-gr . .BR \-gr .
Most of the "basic" switches can be abbreviated to as little as one letter. Most of the "basic" switches can be abbreviated to as little as one letter.
Upper and lower case are equivalent (thus Upper and lower case are equivalent (thus
.B \-GIF .B \-BMP
is the same as is the same as
.BR \-gif ). .BR \-bmp ).
British spellings are also accepted (e.g., British spellings are also accepted (e.g.,
.BR \-greyscale ), .BR \-greyscale ),
though for brevity these are not mentioned below. though for brevity these are not mentioned below.
@@ -182,13 +182,13 @@ Same as
.BR \-verbose . .BR \-verbose .
.SH EXAMPLES .SH EXAMPLES
.LP .LP
This example decompresses the JPEG file foo.jpg, automatically quantizes to This example decompresses the JPEG file foo.jpg, quantizes it to
256 colors, and saves the output in GIF format in foo.gif: 256 colors, and saves the output in 8-bit BMP format in foo.bmp:
.IP .IP
.B djpeg \-gif .B djpeg \-colors 256 \-bmp
.I foo.jpg .I foo.jpg
.B > .B >
.I foo.gif .I foo.bmp
.SH HINTS .SH HINTS
To get a quick preview of an image, use the To get a quick preview of an image, use the
.B \-grayscale .B \-grayscale
@@ -245,4 +245,9 @@ Independent JPEG Group
.SH BUGS .SH BUGS
Arithmetic coding is not supported for legal reasons. Arithmetic coding is not supported for legal reasons.
.PP .PP
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.
.PP
Still not as fast as we'd like. Still not as fast as we'd like.

41
djpeg.c
View File

@@ -1,7 +1,7 @@
/* /*
* djpeg.c * djpeg.c
* *
* Copyright (C) 1991-1995, Thomas G. Lane. * Copyright (C) 1991-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -30,7 +30,8 @@
#ifdef USE_CCOMMAND /* command-line reader for Macintosh */ #ifdef USE_CCOMMAND /* command-line reader for Macintosh */
#ifdef __MWERKS__ #ifdef __MWERKS__
#include <SIOUX.h> /* Metrowerks declares it here */ #include <SIOUX.h> /* Metrowerks needs this */
#include <console.h> /* ... and this */
#endif #endif
#ifdef THINK_C #ifdef THINK_C
#include <console.h> /* Think declares it here */ #include <console.h> /* Think declares it here */
@@ -85,7 +86,7 @@ static const char * progname; /* program name for error messages */
static char * outfilename; /* for -outfile switch */ static char * outfilename; /* for -outfile switch */
LOCAL void LOCAL(void)
usage (void) usage (void)
/* complain about bad command line */ /* complain about bad command line */
{ {
@@ -157,7 +158,7 @@ usage (void)
} }
LOCAL int LOCAL(int)
parse_switches (j_decompress_ptr cinfo, int argc, char **argv, parse_switches (j_decompress_ptr cinfo, int argc, char **argv,
int last_file_arg_seen, boolean for_real) int last_file_arg_seen, boolean for_real)
/* Parse optional switches. /* Parse optional switches.
@@ -343,13 +344,13 @@ 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. * 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. * Note this code relies on a non-suspending data source.
*/ */
LOCAL unsigned int LOCAL(unsigned int)
jpeg_getc (j_decompress_ptr cinfo) jpeg_getc (j_decompress_ptr cinfo)
/* Read next byte */ /* Read next byte */
{ {
@@ -364,8 +365,8 @@ jpeg_getc (j_decompress_ptr cinfo)
} }
METHODDEF boolean METHODDEF(boolean)
COM_handler (j_decompress_ptr cinfo) print_text_marker (j_decompress_ptr cinfo)
{ {
boolean traceit = (cinfo->err->trace_level >= 1); boolean traceit = (cinfo->err->trace_level >= 1);
INT32 length; INT32 length;
@@ -376,8 +377,13 @@ COM_handler (j_decompress_ptr cinfo)
length += jpeg_getc(cinfo); length += jpeg_getc(cinfo);
length -= 2; /* discount the length word itself */ length -= 2; /* discount the length word itself */
if (traceit) if (traceit) {
fprintf(stderr, "Comment, length %ld:\n", (long) length); 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) { while (--length >= 0) {
ch = jpeg_getc(cinfo); ch = jpeg_getc(cinfo);
@@ -414,7 +420,7 @@ COM_handler (j_decompress_ptr cinfo)
* The main program. * The main program.
*/ */
GLOBAL int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
struct jpeg_decompress_struct cinfo; struct jpeg_decompress_struct cinfo;
@@ -444,8 +450,15 @@ main (int argc, char **argv)
jerr.addon_message_table = cdjpeg_message_table; jerr.addon_message_table = cdjpeg_message_table;
jerr.first_addon_message = JMSG_FIRSTADDONCODE; jerr.first_addon_message = JMSG_FIRSTADDONCODE;
jerr.last_addon_message = JMSG_LASTADDONCODE; 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.doc).
*/
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. */ /* Now safe to enable signal catcher. */
#ifdef NEED_SIGNAL_CATCHER #ifdef NEED_SIGNAL_CATCHER

View File

@@ -68,7 +68,7 @@ extern int image_width; /* Number of columns in image */
* and a compression quality factor are passed in. * and a compression quality factor are passed in.
*/ */
GLOBAL void GLOBAL(void)
write_JPEG_file (char * filename, int quality) write_JPEG_file (char * filename, int quality)
{ {
/* This struct contains the JPEG compression parameters and pointers to /* This struct contains the JPEG compression parameters and pointers to
@@ -259,7 +259,7 @@ typedef struct my_error_mgr * my_error_ptr;
* Here's the routine that will replace the standard error_exit method: * Here's the routine that will replace the standard error_exit method:
*/ */
METHODDEF void METHODDEF(void)
my_error_exit (j_common_ptr cinfo) my_error_exit (j_common_ptr cinfo)
{ {
/* cinfo->err really points to a my_error_mgr struct, so coerce pointer */ /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
@@ -280,7 +280,7 @@ my_error_exit (j_common_ptr cinfo)
*/ */
GLOBAL int GLOBAL(int)
read_JPEG_file (char * filename) read_JPEG_file (char * filename)
{ {
/* This struct contains the JPEG decompression parameters and pointers to /* This struct contains the JPEG decompression parameters and pointers to

View File

@@ -1,6 +1,6 @@
IJG JPEG LIBRARY: FILE LIST IJG JPEG LIBRARY: FILE LIST
Copyright (C) 1994-1995, Thomas G. Lane. Copyright (C) 1994-1998, Thomas G. Lane.
This file is part of the Independent JPEG Group's software. This file is part of the Independent JPEG Group's software.
For conditions of distribution and use, see the accompanying README file. For conditions of distribution and use, see the accompanying README file.
@@ -113,8 +113,9 @@ module:
jmemnobs.c "No backing store": assumes adequate virtual memory exists. jmemnobs.c "No backing store": assumes adequate virtual memory exists.
jmemansi.c Makes temporary files with ANSI-standard routine tmpfile(). jmemansi.c Makes temporary files with ANSI-standard routine tmpfile().
jmemname.c Makes temporary files with program-generated file names. jmemname.c Makes temporary files with program-generated file names.
jmemdos.c Custom implementation for MS-DOS: knows about extended and jmemdos.c Custom implementation for MS-DOS (16-bit environment only):
expanded memory as well as temporary files. 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 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.doc for hints about which one to use).
@@ -133,8 +134,9 @@ CJPEG/DJPEG/JPEGTRAN
Include files: Include files:
cdjpeg.h Declarations shared by cjpeg/djpeg modules. cdjpeg.h Declarations shared by cjpeg/djpeg/jpegtran modules.
cderror.h Additional error and trace message codes for cjpeg/djpeg. 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: C source code files:
@@ -145,11 +147,12 @@ cdjpeg.c Utility routines used by all three programs.
rdcolmap.c Code to read a colormap file for djpeg's "-map" switch. 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. rdswitch.c Code to process some of cjpeg's more complex switches.
Also used by jpegtran. Also used by jpegtran.
transupp.c Support code for jpegtran: lossless image manipulations.
Image file reader modules for cjpeg: Image file reader modules for cjpeg:
rdbmp.c BMP file input. 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. rdppm.c PPM/PGM file input.
rdrle.c Utah RLE file input. rdrle.c Utah RLE file input.
rdtarga.c Targa file input. rdtarga.c Targa file input.
@@ -157,7 +160,7 @@ rdtarga.c Targa file input.
Image file writer modules for djpeg: Image file writer modules for djpeg:
wrbmp.c BMP file output. 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. wrppm.c PPM/PGM file output.
wrrle.c Utah RLE file output. wrrle.c Utah RLE file output.
wrtarga.c Targa file output. wrtarga.c Targa file output.
@@ -189,6 +192,11 @@ 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.doc for more info):
configure Unix shell script to perform automatic configuration. configure Unix shell script to perform automatic configuration.
ltconfig Support scripts for configure (from GNU libtool).
ltmain.sh
config.guess
config.sub
install-sh Install shell script for those Unix systems lacking one.
ckconfig.c Program to generate jconfig.h on non-Unix systems. ckconfig.c Program to generate jconfig.h on non-Unix systems.
jconfig.doc Template for making jconfig.h by hand. jconfig.doc Template for making jconfig.h by hand.
makefile.* Sample makefiles for particular systems. makefile.* Sample makefiles for particular systems.

View File

@@ -1,6 +1,6 @@
INSTALLATION INSTRUCTIONS for the Independent JPEG Group's JPEG software INSTALLATION INSTRUCTIONS for the Independent JPEG Group's JPEG software
Copyright (C) 1991-1995, Thomas G. Lane. Copyright (C) 1991-1998, Thomas G. Lane.
This file is part of the Independent JPEG Group's software. This file is part of the Independent JPEG Group's software.
For conditions of distribution and use, see the accompanying README file. For conditions of distribution and use, see the accompanying README file.
@@ -94,6 +94,19 @@ 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 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: override. You can do this by providing optional switches to configure:
* If you want to build libjpeg as a shared library, say
./configure --enable-shared
To get both shared and static libraries, say
./configure --enable-shared --enable-static
Note that these switches invoke GNU libtool to take care of system-dependent
shared library building methods. If things don't work this way, please try
running configure without either switch; that should build a static library
without using libtool. If that works, your problem is probably with libtool
not with the IJG code. libtool is fairly new and doesn't support all flavors
of Unix yet. (You might be able to find a newer version of libtool than the
one included with libjpeg; see ftp.gnu.org. Report libtool problems to
bug-libtool@gnu.org.)
* Configure will use gcc (GNU C compiler) if it's available, otherwise cc. * 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 To force a particular compiler to be selected, use the CC option, for example
./configure CC='cc' ./configure CC='cc'
@@ -102,8 +115,10 @@ For example, on HP-UX you probably want to say
./configure CC='cc -Aa' ./configure CC='cc -Aa'
to get HP's compiler to run in ANSI mode. to get HP's compiler to run in ANSI mode.
* The default CFLAGS setting is "-O". You can override this by saying, * The default CFLAGS setting is "-O" for non-gcc compilers, "-O2" for gcc.
for example, ./configure CFLAGS='-O2'. You can override this by saying, for example,
./configure CFLAGS='-g'
if you want to compile with debugging support.
* Configure will set up the makefile so that "make install" will install files * 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 into /usr/local/bin, /usr/local/man, etc. You can specify an installation
@@ -131,17 +146,20 @@ Makefile jconfig file System and/or compiler
makefile.manx jconfig.manx Amiga, Manx Aztec C makefile.manx jconfig.manx Amiga, Manx Aztec C
makefile.sas jconfig.sas Amiga, SAS 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 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.bcc jconfig.bcc MS-DOS or OS/2, Borland C
makefile.dj jconfig.dj MS-DOS, DJGPP (Delorie's port of GNU 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.wat jconfig.wat MS-DOS, OS/2, or Windows NT, Watcom C
makefile.vc jconfig.vc Windows NT/95, MS Visual C++
make*.ds jconfig.vc Windows NT/95, MS Developer Studio
makefile.mms jconfig.vms Digital VMS, with MMS software makefile.mms jconfig.vms Digital VMS, with MMS software
makefile.vms jconfig.vms Digital VMS, without MMS software makefile.vms jconfig.vms Digital VMS, without MMS software
Copy the proper jconfig file to jconfig.h and the makefile to Makefile Copy the proper jconfig file to jconfig.h and the makefile to Makefile (or
(or whatever your system uses as the standard makefile name). For the whatever your system uses as the standard makefile name). For more info see
Atari, we provide four project files; see the Atari hints below. the appropriate system-specific hints section near the end of this file.
Configuring the software by hand Configuring the software by hand
@@ -216,7 +234,7 @@ Selecting a memory manager
The IJG code is capable of working on images that are too big to fit in main The IJG code is capable of working on images that are too big to fit in main
memory; data is swapped out to temporary files as necessary. However, the memory; data is swapped out to temporary files as necessary. However, the
code to do this is rather system-dependent. We provide four different code to do this is rather system-dependent. We provide five different
memory managers: memory managers:
* jmemansi.c This version uses the ANSI-standard library routine tmpfile(), * jmemansi.c This version uses the ANSI-standard library routine tmpfile(),
@@ -240,7 +258,10 @@ memory managers:
IMPORTANT: if you use this, define USE_MSDOS_MEMMGR in IMPORTANT: if you use this, define USE_MSDOS_MEMMGR in
jconfig.h, and include the assembly file jmemdosa.asm in the jconfig.h, and include the assembly file jmemdosa.asm in the
programs. The supplied makefiles and jconfig files for programs. The supplied makefiles and jconfig files for
MS-DOS compilers already do both. 16-bit MS-DOS compilers already do both.
* jmemmac.c Custom version for Apple Macintosh; see the system-specific
notes for Macintosh for more info.
To use a particular memory manager, change the SYSDEPMEM variable in your To use a particular memory manager, change the SYSDEPMEM variable in your
makefile to equal the corresponding object file name (for example, jmemansi.o makefile to equal the corresponding object file name (for example, jmemansi.o
@@ -253,8 +274,8 @@ If yours doesn't, try jmemansi.c first. If that doesn't compile, you'll have
to use jmemname.c; be sure to adjust select_file_name() for local conditions. to use jmemname.c; be sure to adjust select_file_name() for local conditions.
You may also need to change unlink() to remove() in close_backing_store(). You may also need to change unlink() to remove() in close_backing_store().
Except with jmemnobs.c, you need to adjust the DEFAULT_MAX_MEM setting to a Except with jmemnobs.c or jmemmac.c, you need to adjust the DEFAULT_MAX_MEM
reasonable value for your system (either by adding a #define for setting to a reasonable value for your system (either by adding a #define for
DEFAULT_MAX_MEM to jconfig.h, or by adding a -D switch to the Makefile). DEFAULT_MAX_MEM to jconfig.h, or by adding a -D switch to the Makefile).
This value limits the amount of data space the program will attempt to This value limits the amount of data space the program will attempt to
allocate. Code and static data space isn't counted, so the actual memory allocate. Code and static data space isn't counted, so the actual memory
@@ -300,7 +321,7 @@ As a quick test of functionality we've included a small sample image in
several forms: several forms:
testorig.jpg Starting point for the djpeg tests. testorig.jpg Starting point for the djpeg tests.
testimg.ppm The output of djpeg testorig.jpg 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 testimg.jpg The output of cjpeg testimg.ppm
testprog.jpg Progressive-mode equivalent of testorig.jpg. testprog.jpg Progressive-mode equivalent of testorig.jpg.
testimgp.jpg The output of cjpeg -progressive -optimize testimg.ppm testimgp.jpg The output of cjpeg -progressive -optimize testimg.ppm
@@ -336,10 +357,10 @@ check fails, try recompiling with USE_SETMODE or USE_FDOPEN defined.
If it still doesn't work, better use two-file style. 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 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 temporary-file usage works. Try "djpeg -bmp -colors 256 -max 0 testorig.jpg"
sure its output matches testimg.gif. If you have any really large images and make sure its output matches testimg.bmp. If you have any really large
handy, try compressing them with -optimize and/or decompressing with -gif to images handy, try compressing them with -optimize and/or decompressing with
make sure your DEFAULT_MAX_MEM setting is not too large. -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, 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 such as 1-pass color quantization, are not exercised at all. It's just a
@@ -354,7 +375,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) copying the executable files (cjpeg, djpeg, jpegtran, rdjpgcom, and wrjpgcom)
to wherever you normally install programs. On Unix systems, you'll also want 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) 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 since there's such a wide variety of installation procedures on different
systems. systems.
@@ -367,8 +388,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 the Makefile, particularly if your system's conventions for man page
filenames don't match what configure expects. filenames don't match what configure expects.
If you want to install the library file libjpeg.a and the include files j*.h If you want to install the IJG library itself, for use in compiling other
(for use in compiling other programs besides the IJG ones), then say 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 make install-lib
@@ -423,8 +449,8 @@ 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 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 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 (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 officially supported by the PBMPLUS library, but it is expected that a
next release of PBMPLUS will support it. Note that the PPM reader will 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 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 data is automatically rescaled to either maxval=255 or maxval=4095 as
appropriate for the cjpeg bit depth. appropriate for the cjpeg bit depth.
@@ -565,19 +591,19 @@ Atari ST/STE/TT:
Copy the project files makcjpeg.st, makdjpeg.st, maktjpeg.st, and makljpeg.st 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 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 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 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 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 less than your normal free memory. Put "#define DEFAULT_MAX_MEM nnnn" into
jconfig.h to do this. jconfig.h to do this.
To use the 68881/68882 coprocessor for the floating point DCT, add the 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 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 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 coprocessor, you may prefer to remove the float DCT code by undefining
DCT_FLOAT_SUPPORTED in jmorecfg.h (since without a coprocessor, the float 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 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, 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. or jpegtran.ttp. You'll have to perform the self-test by hand.
@@ -627,38 +653,69 @@ to A.08.07. If you get complaints about "not a typedef name", you'll have to
use makefile.unix, or run configure without the CC option. use makefile.unix, or run configure without the CC option.
Macintosh, MPW: Macintosh, generic comments:
We don't directly support MPW in the current release, but Larry Rosenstein The supplied user-interface files (cjpeg.c, djpeg.c, etc) are set up to
ported an earlier version of the IJG code without very much trouble. There's provide a Unix-style command line interface. You can use this interface on
useful notes and conversion scripts in his kit for porting PBMPLUS to MPW. the Mac by means of the ccommand() library routine provided by Metrowerks
You can obtain the kit by FTP to ftp.apple.com, files /pub/lsr/pbmplus-port*. 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. 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.
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.
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: Macintosh, Metrowerks CodeWarrior:
Metrowerks release DR2 has problems with the IJG code; don't use it. Release The Unix-command-line-style interface can be used by defining USE_CCOMMAND.
DR3.5 or later should be OK. 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
The command-line-style interface can be used by defining USE_CCOMMAND and input and output file names in the "Arguments" text-edit box, rather than
TWO_FILE_COMMANDLINE (see next entry for more details). 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 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 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. 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: Macintosh, Think C:
The supplied user-interface files (cjpeg.c and djpeg.c) are set up to provide The documentation in Jim Brunner's "JPEG Convert" source code (see above)
a Unix-style command line interface. You can use this interface on the Mac includes detailed build instructions for Think C; it's probably somewhat
by means of Think's ccommand() library routine. However, a much better out of date for the current release, but may be helpful.
Mac-style user interface has been prepared by Jim Brunner. You can obtain
the additional source code needed for that user interface by FTP to
sumex-aim.stanford.edu, file /info-mac/dev/src/jpeg-convert-c.hqx. Jim's
documentation also includes more detailed build instructions for Think C.
(Jim is working on updating this code to work with v5 of the IJG library,
but it wasn't ready as of v5 release time. Should be out before too long.)
If you want to build the minimal command line version, proceed as follows. 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 You'll have to prepare project files for the programs; we don't include any
@@ -674,6 +731,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. 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. 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: MIPS R3000:
@@ -684,7 +744,7 @@ Note that the R3000 chip is found in workstations from DEC and others.
MS-DOS, generic comments for 16-bit compilers: 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"; 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 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 compile cjpeg or djpeg by itself, but you will probably have to use medium
@@ -700,7 +760,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 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 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 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.) 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 When using jmemdos.c, jconfig.h must define USE_MSDOS_MEMMGR and must set
@@ -757,23 +817,22 @@ jconfig.bcc already includes #define USE_SETMODE to make this work.
(fdopen does not work correctly.) (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: MS-DOS, Microsoft C:
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. If you want one-file command line style, just undefine TWO_FILE_COMMANDLINE.
jconfig.mc6 already includes #define USE_SETMODE to make this work. jconfig.mc6 already includes #define USE_SETMODE to make this work.
(fdopen does not work correctly.) (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 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). 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 If this happens to you, the easiest solution is to change TRACEMS8 to
@@ -784,11 +843,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 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). 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 MS C 8.0 crashes when compiling jquant1.c with optimization switch /Oo ...
(yes, off). 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". 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. The IJG code also defines typedef boolean, but we make it "int" by default.
@@ -796,24 +856,104 @@ 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 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 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 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 is to make the IJG library use "unsigned char" for boolean. To do that,
making that part of jmorecfg.h read like this: 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 */ #ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */
typedef unsigned char boolean; typedef unsigned char boolean;
#endif #endif
#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.
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
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. (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. (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 Many people want to convert the IJG library into a DLL. This is reasonably
straightforward, but watch out for the following: straightforward, but watch out for the following:
1. Don't try to compile as a DLL in small or medium memory model; use 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 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; assume the address of a local variable is an ordinary (not FAR) pointer;
that isn't true in a medium-model DLL. that isn't true in a medium-model DLL.
2. Microsoft C cannot pass file pointers between applications and DLLs. 2. Microsoft C cannot pass file pointers between applications and DLLs.
(See Microsoft Knowledge Base, PSS ID Number Q50336.) So jdatasrc.c and (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 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 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. 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
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 _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.
The unmodified IJG library presents a very C-specific application interface, The unmodified IJG library presents a very C-specific application interface,
so the resulting DLL is only usable from C or C++ applications. There has so the resulting DLL is only usable from C or C++ applications. There has
been some talk of writing wrapper code that would present a simpler interface been some talk of writing wrapper code that would present a simpler interface
@@ -823,23 +963,85 @@ but hasn't been very high priority --- any volunteers out there?
Microsoft Windows, Borland C: 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 Borland C++ 4.5 fails with an internal compiler error when trying to compile
jdmerge.c. If enough people complain, perhaps Borland will fix it. jdmerge.c in 32-bit mode. If enough people complain, perhaps Borland will fix
In the meantime, you can work around the problem by undefining it. In the meantime, the simplest known workaround is to add a redundant
UPSAMPLE_MERGING_SUPPORTED in jmorecfg.h, at the price of losing most of the definition of the variable range_limit in h2v1_merged_upsample(), at the head
speedup from the "-nosmooth" decompression option. Alternatively, I'm told of the block that handles odd image width (about line 268 in v6 jdmerge.c):
that replacing three or more uses of h2v1_merged_upsample()'s variable /* If image width is odd, do the last output column separately */
"range_limit" with direct references to "cinfo->sample_range_limit" makes if (cinfo->output_width & 1) {
the problem go away, though the routine is then a little slower than it register JSAMPLE * range_limit = cinfo->sample_range_limit; /* ADD THIS */
should be. Pretty bizarre, especially since the very similar routine cb = GETJSAMPLE(*inptr1);
h2v2_merged_upsample doesn't trigger the bug. Pretty bizarre, especially since the very similar routine h2v2_merged_upsample
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.)
Some users feel that it's easier to call the library from C++ code if you
force VC++ to treat the library as C++ code, which you can do by renaming
all the *.c files to *.cpp (and adjusting the makefile to match). This
avoids the need to put extern "C" { ... } around #include "jpeglib.h" in
your C++ application.
Microsoft Windows, Microsoft Developer Studio:
We include makefiles that should work as project files in DevStudio 4.2 or
later. There is a library makefile that builds the IJG library as a static
Win32 library, and an application makefile that builds 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. Copy jconfig.vc to jconfig.h, makelib.ds to jpeg.mak, and
makeapps.ds to apps.mak. (Note that the renaming is critical!)
2. Click on the .mak files to construct project workspaces.
(If you are using DevStudio more recent than 4.2, you'll probably
get a message saying that the makefiles are being updated.)
3. Build the library project, then the applications project.
4. Move the application .exe files from `app`\Release to an
appropriate location on your path.
5. To perform the self-test, execute the command line
NMAKE /f makefile.vc test
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: SGI:
Set "AR2= ar -ts" rather than "AR2= ranlib" in the Makefile. If you are On some SGI systems, you may need to set "AR2= ar -ts" in the Makefile.
using configure, you should say If you are using configure, you can do this by saying
./configure RANLIB='ar -ts' ./configure RANLIB='ar -ts'
This change is not needed on all SGIs. Use it only if the make fails at the
stage of linking the completed programs.
On the MIPS R4000 architecture (Indy, etc.), the compiler option "-mips2" On the MIPS R4000 architecture (Indy, etc.), the compiler option "-mips2"
reportedly speeds up the float DCT method substantially, enough to make it reportedly speeds up the float DCT method substantially, enough to make it

View File

@@ -1,7 +1,7 @@
/* /*
* jcapimin.c * jcapimin.c
* *
* Copyright (C) 1994-1995, Thomas G. Lane. * Copyright (C) 1994-1998, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -26,18 +26,31 @@
* The error manager must already be set up (in case memory manager fails). * The error manager must already be set up (in case memory manager fails).
*/ */
GLOBAL void GLOBAL(void)
jpeg_create_compress (j_compress_ptr cinfo) jpeg_CreateCompress (j_compress_ptr cinfo, int version, size_t structsize)
{ {
int i; int i;
/* For debugging purposes, zero the whole master structure. /* Guard against version mismatches between library and caller. */
* But error manager pointer is already there, so save and restore it. cinfo->mem = NULL; /* so jpeg_destroy knows mem mgr not called */
if (version != JPEG_LIB_VERSION)
ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version);
if (structsize != SIZEOF(struct jpeg_compress_struct))
ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE,
(int) SIZEOF(struct jpeg_compress_struct), (int) structsize);
/* 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; struct jpeg_error_mgr * err = cinfo->err;
void * client_data = cinfo->client_data; /* ignore Purify complaint here */
MEMZERO(cinfo, SIZEOF(struct jpeg_compress_struct)); MEMZERO(cinfo, SIZEOF(struct jpeg_compress_struct));
cinfo->err = err; cinfo->err = err;
cinfo->client_data = client_data;
} }
cinfo->is_decompressor = FALSE; cinfo->is_decompressor = FALSE;
@@ -58,6 +71,8 @@ jpeg_create_compress (j_compress_ptr cinfo)
cinfo->ac_huff_tbl_ptrs[i] = NULL; cinfo->ac_huff_tbl_ptrs[i] = NULL;
} }
cinfo->script_space = NULL;
cinfo->input_gamma = 1.0; /* in case application forgets */ cinfo->input_gamma = 1.0; /* in case application forgets */
/* OK, I'm ready */ /* OK, I'm ready */
@@ -69,7 +84,7 @@ jpeg_create_compress (j_compress_ptr cinfo)
* Destruction of a JPEG compression object * Destruction of a JPEG compression object
*/ */
GLOBAL void GLOBAL(void)
jpeg_destroy_compress (j_compress_ptr cinfo) jpeg_destroy_compress (j_compress_ptr cinfo)
{ {
jpeg_destroy((j_common_ptr) cinfo); /* use common routine */ jpeg_destroy((j_common_ptr) cinfo); /* use common routine */
@@ -81,7 +96,7 @@ jpeg_destroy_compress (j_compress_ptr cinfo)
* but don't destroy the object itself. * but don't destroy the object itself.
*/ */
GLOBAL void GLOBAL(void)
jpeg_abort_compress (j_compress_ptr cinfo) jpeg_abort_compress (j_compress_ptr cinfo)
{ {
jpeg_abort((j_common_ptr) cinfo); /* use common routine */ jpeg_abort((j_common_ptr) cinfo); /* use common routine */
@@ -100,7 +115,7 @@ jpeg_abort_compress (j_compress_ptr cinfo)
* jcparam.o would be linked whether the application used it or not. * jcparam.o would be linked whether the application used it or not.
*/ */
GLOBAL void GLOBAL(void)
jpeg_suppress_tables (j_compress_ptr cinfo, boolean suppress) jpeg_suppress_tables (j_compress_ptr cinfo, boolean suppress)
{ {
int i; int i;
@@ -128,7 +143,7 @@ jpeg_suppress_tables (j_compress_ptr cinfo, boolean suppress)
* work including most of the actual output. * work including most of the actual output.
*/ */
GLOBAL void GLOBAL(void)
jpeg_finish_compress (j_compress_ptr cinfo) jpeg_finish_compress (j_compress_ptr cinfo)
{ {
JDIMENSION iMCU_row; JDIMENSION iMCU_row;
@@ -173,9 +188,30 @@ jpeg_finish_compress (j_compress_ptr cinfo)
* first call to jpeg_write_scanlines() or jpeg_write_raw_data(). * first call to jpeg_write_scanlines() or jpeg_write_raw_data().
*/ */
GLOBAL void GLOBAL(void)
jpeg_write_marker (j_compress_ptr cinfo, int marker, jpeg_write_marker (j_compress_ptr cinfo, int marker,
const JOCTET *dataptr, unsigned int datalen) 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_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 || if (cinfo->next_scanline != 0 ||
(cinfo->global_state != CSTATE_SCANNING && (cinfo->global_state != CSTATE_SCANNING &&
@@ -183,7 +219,13 @@ jpeg_write_marker (j_compress_ptr cinfo, int marker,
cinfo->global_state != CSTATE_WRCOEFS)) cinfo->global_state != CSTATE_WRCOEFS))
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); 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);
}
GLOBAL(void)
jpeg_write_m_byte (j_compress_ptr cinfo, int val)
{
(*cinfo->marker->write_marker_byte) (cinfo, val);
} }
@@ -208,7 +250,7 @@ jpeg_write_marker (j_compress_ptr cinfo, int marker,
* will not re-emit the tables unless it is passed write_all_tables=TRUE. * will not re-emit the tables unless it is passed write_all_tables=TRUE.
*/ */
GLOBAL void GLOBAL(void)
jpeg_write_tables (j_compress_ptr cinfo) jpeg_write_tables (j_compress_ptr cinfo)
{ {
if (cinfo->global_state != CSTATE_START) if (cinfo->global_state != CSTATE_START)
@@ -223,6 +265,16 @@ jpeg_write_tables (j_compress_ptr cinfo)
(*cinfo->marker->write_tables_only) (cinfo); (*cinfo->marker->write_tables_only) (cinfo);
/* And clean up. */ /* And clean up. */
(*cinfo->dest->term_destination) (cinfo); (*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().
*/
} }

View File

@@ -1,7 +1,7 @@
/* /*
* jcapistd.c * jcapistd.c
* *
* Copyright (C) 1994-1995, Thomas G. Lane. * Copyright (C) 1994-1996, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -34,7 +34,7 @@
* wrong thing. * wrong thing.
*/ */
GLOBAL void GLOBAL(void)
jpeg_start_compress (j_compress_ptr cinfo, boolean write_all_tables) jpeg_start_compress (j_compress_ptr cinfo, boolean write_all_tables)
{ {
if (cinfo->global_state != CSTATE_START) if (cinfo->global_state != CSTATE_START)
@@ -73,7 +73,7 @@ jpeg_start_compress (j_compress_ptr cinfo, boolean write_all_tables)
* when using a multiple-scanline buffer. * when using a multiple-scanline buffer.
*/ */
GLOBAL JDIMENSION GLOBAL(JDIMENSION)
jpeg_write_scanlines (j_compress_ptr cinfo, JSAMPARRAY scanlines, jpeg_write_scanlines (j_compress_ptr cinfo, JSAMPARRAY scanlines,
JDIMENSION num_lines) JDIMENSION num_lines)
{ {
@@ -116,7 +116,7 @@ jpeg_write_scanlines (j_compress_ptr cinfo, JSAMPARRAY scanlines,
* Processes exactly one iMCU row per call, unless suspended. * Processes exactly one iMCU row per call, unless suspended.
*/ */
GLOBAL JDIMENSION GLOBAL(JDIMENSION)
jpeg_write_raw_data (j_compress_ptr cinfo, JSAMPIMAGE data, jpeg_write_raw_data (j_compress_ptr cinfo, JSAMPIMAGE data,
JDIMENSION num_lines) JDIMENSION num_lines)
{ {

View File

@@ -1,7 +1,7 @@
/* /*
* jccoefct.c * jccoefct.c
* *
* Copyright (C) 1994-1995, Thomas G. Lane. * Copyright (C) 1994-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -58,17 +58,17 @@ typedef my_coef_controller * my_coef_ptr;
/* Forward declarations */ /* Forward declarations */
METHODDEF boolean compress_data METHODDEF(boolean) compress_data
JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf)); JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
#ifdef FULL_COEF_BUFFER_SUPPORTED #ifdef FULL_COEF_BUFFER_SUPPORTED
METHODDEF boolean compress_first_pass METHODDEF(boolean) compress_first_pass
JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf)); JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
METHODDEF boolean compress_output METHODDEF(boolean) compress_output
JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf)); JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
#endif #endif
LOCAL void LOCAL(void)
start_iMCU_row (j_compress_ptr cinfo) start_iMCU_row (j_compress_ptr cinfo)
/* Reset within-iMCU-row counters for a new row */ /* Reset within-iMCU-row counters for a new row */
{ {
@@ -96,7 +96,7 @@ start_iMCU_row (j_compress_ptr cinfo)
* Initialize for a processing pass. * Initialize for a processing pass.
*/ */
METHODDEF void METHODDEF(void)
start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode) start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
{ {
my_coef_ptr coef = (my_coef_ptr) cinfo->coef; my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
@@ -135,11 +135,11 @@ 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. * 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. * Returns TRUE if the iMCU row is completed, FALSE if suspended.
* *
* NB: input_buf contains a plane for each component in image. * NB: input_buf contains a plane for each component in image,
* For single pass, this is the same as the components in the scan. * which we index according to the component's SOF position.
*/ */
METHODDEF boolean METHODDEF(boolean)
compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf) compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
{ {
my_coef_ptr coef = (my_coef_ptr) cinfo->coef; my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
@@ -175,7 +175,8 @@ compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
if (coef->iMCU_row_num < last_iMCU_row || if (coef->iMCU_row_num < last_iMCU_row ||
yoffset+yindex < compptr->last_row_height) { yoffset+yindex < compptr->last_row_height) {
(*cinfo->fdct->forward_DCT) (cinfo, compptr, (*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); ypos, xpos, (JDIMENSION) blockcnt);
if (blockcnt < compptr->MCU_width) { if (blockcnt < compptr->MCU_width) {
/* Create some dummy blocks at the right edge of the image. */ /* Create some dummy blocks at the right edge of the image. */
@@ -240,7 +241,7 @@ compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
* at the scan-dependent variables (MCU dimensions, etc). * at the scan-dependent variables (MCU dimensions, etc).
*/ */
METHODDEF boolean METHODDEF(boolean)
compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf) compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
{ {
my_coef_ptr coef = (my_coef_ptr) cinfo->coef; my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
@@ -336,7 +337,7 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
* NB: input_buf is ignored; it is likely to be a NULL pointer. * NB: input_buf is ignored; it is likely to be a NULL pointer.
*/ */
METHODDEF boolean METHODDEF(boolean)
compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf) compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
{ {
my_coef_ptr coef = (my_coef_ptr) cinfo->coef; my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
@@ -400,7 +401,7 @@ compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
* Initialize coefficient buffer controller. * Initialize coefficient buffer controller.
*/ */
GLOBAL void GLOBAL(void)
jinit_c_coef_controller (j_compress_ptr cinfo, boolean need_full_buffer) jinit_c_coef_controller (j_compress_ptr cinfo, boolean need_full_buffer)
{ {
my_coef_ptr coef; my_coef_ptr coef;

168
jccolor.c
View File

@@ -1,7 +1,9 @@
/* /*
* jccolor.c * jccolor.c
* *
* Copyright (C) 1991-1994, Thomas G. Lane. * 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. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -11,6 +13,7 @@
#define JPEG_INTERNALS #define JPEG_INTERNALS
#include "jinclude.h" #include "jinclude.h"
#include "jpeglib.h" #include "jpeglib.h"
#include "jsimd.h"
/* Private subobject */ /* Private subobject */
@@ -78,11 +81,79 @@ typedef my_color_converter * my_cconvert_ptr;
#define TABLE_SIZE (8*(MAXJSAMPLE+1)) #define TABLE_SIZE (8*(MAXJSAMPLE+1))
#if BITS_IN_JSAMPLE == 8
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
};
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
};
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. * Initialize for RGB->YCC colorspace conversion.
*/ */
METHODDEF void METHODDEF(void)
rgb_ycc_start (j_compress_ptr cinfo) rgb_ycc_start (j_compress_ptr cinfo)
{ {
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
@@ -126,7 +197,7 @@ rgb_ycc_start (j_compress_ptr cinfo)
* offset required on that side. * offset required on that side.
*/ */
METHODDEF void METHODDEF(void)
rgb_ycc_convert (j_compress_ptr cinfo, rgb_ycc_convert (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JSAMPIMAGE output_buf, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
JDIMENSION output_row, int num_rows) JDIMENSION output_row, int num_rows)
@@ -146,10 +217,10 @@ rgb_ycc_convert (j_compress_ptr cinfo,
outptr2 = output_buf[2][output_row]; outptr2 = output_buf[2][output_row];
output_row++; output_row++;
for (col = 0; col < num_cols; col++) { for (col = 0; col < num_cols; col++) {
r = GETJSAMPLE(inptr[RGB_RED]); r = GETJSAMPLE(inptr[rgb_red[cinfo->in_color_space]]);
g = GETJSAMPLE(inptr[RGB_GREEN]); g = GETJSAMPLE(inptr[rgb_green[cinfo->in_color_space]]);
b = GETJSAMPLE(inptr[RGB_BLUE]); b = GETJSAMPLE(inptr[rgb_blue[cinfo->in_color_space]]);
inptr += RGB_PIXELSIZE; inptr += rgb_pixelsize[cinfo->in_color_space];
/* If the inputs are 0..MAXJSAMPLE, the outputs of these equations /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
* must be too; we do not need an explicit range-limiting operation. * must be too; we do not need an explicit range-limiting operation.
* Hence the value being shifted is never negative, and we don't * Hence the value being shifted is never negative, and we don't
@@ -182,32 +253,42 @@ rgb_ycc_convert (j_compress_ptr cinfo,
* We assume rgb_ycc_start has been called (we only use the Y tables). * We assume rgb_ycc_start has been called (we only use the Y tables).
*/ */
METHODDEF void METHODDEF(void)
rgb_gray_convert (j_compress_ptr cinfo, rgb_gray_convert (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JSAMPIMAGE output_buf, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
JDIMENSION output_row, int num_rows) JDIMENSION output_row, int num_rows)
{ {
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; 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; register INT32 * ctab = cconvert->rgb_ycc_tab;
#endif
register JSAMPROW inptr; register JSAMPROW inptr;
register JSAMPROW outptr; register JSAMPROW outptr;
JSAMPLE *maxoutptr;
register JDIMENSION col; register JDIMENSION col;
JDIMENSION num_cols = cinfo->image_width; 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) { while (--num_rows >= 0) {
inptr = *input_buf++; inptr = *input_buf++;
outptr = output_buf[0][output_row]; outptr = output_buf[0][output_row];
maxoutptr = &outptr[num_cols];
output_row++; output_row++;
for (col = 0; col < num_cols; col++) { for (; outptr < maxoutptr; outptr++, inptr += rgbstride) {
r = GETJSAMPLE(inptr[RGB_RED]);
g = GETJSAMPLE(inptr[RGB_GREEN]);
b = GETJSAMPLE(inptr[RGB_BLUE]);
inptr += RGB_PIXELSIZE;
/* Y */ /* Y */
outptr[col] = (JSAMPLE) #if BITS_IN_JSAMPLE == 8
((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) *outptr = red_lut[inptr[rindex]] + green_lut[inptr[gindex]]
>> SCALEBITS); + 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
} }
} }
} }
@@ -221,7 +302,7 @@ rgb_gray_convert (j_compress_ptr cinfo,
* We assume rgb_ycc_start has been called. * We assume rgb_ycc_start has been called.
*/ */
METHODDEF void METHODDEF(void)
cmyk_ycck_convert (j_compress_ptr cinfo, cmyk_ycck_convert (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JSAMPIMAGE output_buf, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
JDIMENSION output_row, int num_rows) JDIMENSION output_row, int num_rows)
@@ -276,7 +357,7 @@ cmyk_ycck_convert (j_compress_ptr cinfo,
* The source can be either plain grayscale or YCbCr (since Y == gray). * The source can be either plain grayscale or YCbCr (since Y == gray).
*/ */
METHODDEF void METHODDEF(void)
grayscale_convert (j_compress_ptr cinfo, grayscale_convert (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JSAMPIMAGE output_buf, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
JDIMENSION output_row, int num_rows) JDIMENSION output_row, int num_rows)
@@ -305,7 +386,7 @@ grayscale_convert (j_compress_ptr cinfo,
* We assume input_components == num_components. * We assume input_components == num_components.
*/ */
METHODDEF void METHODDEF(void)
null_convert (j_compress_ptr cinfo, null_convert (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JSAMPIMAGE output_buf, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
JDIMENSION output_row, int num_rows) JDIMENSION output_row, int num_rows)
@@ -337,7 +418,7 @@ null_convert (j_compress_ptr cinfo,
* Empty method for start_pass. * Empty method for start_pass.
*/ */
METHODDEF void METHODDEF(void)
null_method (j_compress_ptr cinfo) null_method (j_compress_ptr cinfo)
{ {
/* no work needed */ /* no work needed */
@@ -348,7 +429,7 @@ null_method (j_compress_ptr cinfo)
* Module initialization routine for input colorspace conversion. * Module initialization routine for input colorspace conversion.
*/ */
GLOBAL void GLOBAL(void)
jinit_color_converter (j_compress_ptr cinfo) jinit_color_converter (j_compress_ptr cinfo)
{ {
my_cconvert_ptr cconvert; my_cconvert_ptr cconvert;
@@ -368,11 +449,15 @@ jinit_color_converter (j_compress_ptr cinfo)
break; break;
case JCS_RGB: case JCS_RGB:
#if RGB_PIXELSIZE != 3 case JCS_EXT_RGB:
if (cinfo->input_components != RGB_PIXELSIZE) 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); ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
break; break;
#endif /* else share code with YCbCr */
case JCS_YCbCr: case JCS_YCbCr:
if (cinfo->input_components != 3) if (cinfo->input_components != 3)
@@ -398,7 +483,13 @@ jinit_color_converter (j_compress_ptr cinfo)
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
if (cinfo->in_color_space == JCS_GRAYSCALE) if (cinfo->in_color_space == JCS_GRAYSCALE)
cconvert->pub.color_convert = grayscale_convert; 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.start_pass = rgb_ycc_start;
cconvert->pub.color_convert = rgb_gray_convert; cconvert->pub.color_convert = rgb_gray_convert;
} else if (cinfo->in_color_space == JCS_YCbCr) } else if (cinfo->in_color_space == JCS_YCbCr)
@@ -408,9 +499,16 @@ jinit_color_converter (j_compress_ptr cinfo)
break; break;
case JCS_RGB: 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) if (cinfo->num_components != 3)
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); 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; cconvert->pub.color_convert = null_convert;
else else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
@@ -419,9 +517,19 @@ jinit_color_converter (j_compress_ptr cinfo)
case JCS_YCbCr: case JCS_YCbCr:
if (cinfo->num_components != 3) if (cinfo->num_components != 3)
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
if (cinfo->in_color_space == JCS_RGB) { if (cinfo->in_color_space == JCS_RGB ||
cconvert->pub.start_pass = rgb_ycc_start; cinfo->in_color_space == JCS_EXT_RGB ||
cconvert->pub.color_convert = rgb_ycc_convert; 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) } else if (cinfo->in_color_space == JCS_YCbCr)
cconvert->pub.color_convert = null_convert; cconvert->pub.color_convert = null_convert;
else else

View File

@@ -1,7 +1,9 @@
/* /*
* jcdctmgr.c * jcdctmgr.c
* *
* Copyright (C) 1994-1995, Thomas G. Lane. * 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. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -15,33 +17,180 @@
#include "jinclude.h" #include "jinclude.h"
#include "jpeglib.h" #include "jpeglib.h"
#include "jdct.h" /* Private declarations for DCT subsystem */ #include "jdct.h" /* Private declarations for DCT subsystem */
#include "jsimddct.h"
/* Private subobject for this module */ /* 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 { typedef struct {
struct jpeg_forward_dct pub; /* public fields */ struct jpeg_forward_dct pub; /* public fields */
/* Pointer to the DCT routine actually in use */ /* 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 /* The actual post-DCT divisors --- not identical to the quant table
* entries, because of scaling (especially for an unnormalized DCT). * entries, because of scaling (especially for an unnormalized DCT).
* Each table is given in normal array order; note that this must * Each table is given in normal array order.
* be converted from the zigzag order of the quantization tables.
*/ */
DCTELEM * divisors[NUM_QUANT_TBLS]; DCTELEM * divisors[NUM_QUANT_TBLS];
/* work area for FDCT subroutine */
DCTELEM * workspace;
#ifdef DCT_FLOAT_SUPPORTED #ifdef DCT_FLOAT_SUPPORTED
/* Same as above for the floating-point case. */ /* 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_divisors[NUM_QUANT_TBLS];
FAST_FLOAT * float_workspace;
#endif #endif
} my_fdct_controller; } my_fdct_controller;
typedef my_fdct_controller * my_fdct_ptr; 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. * Initialize for a processing pass.
* Verify that all referenced Q-tables are present, and set up * Verify that all referenced Q-tables are present, and set up
@@ -51,7 +200,7 @@ typedef my_fdct_controller * my_fdct_ptr;
* first scan. Hence all components should be examined here. * first scan. Hence all components should be examined here.
*/ */
METHODDEF void METHODDEF(void)
start_pass_fdctmgr (j_compress_ptr cinfo) start_pass_fdctmgr (j_compress_ptr cinfo)
{ {
my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct; my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
@@ -79,11 +228,11 @@ start_pass_fdctmgr (j_compress_ptr cinfo)
if (fdct->divisors[qtblno] == NULL) { if (fdct->divisors[qtblno] == NULL) {
fdct->divisors[qtblno] = (DCTELEM *) fdct->divisors[qtblno] = (DCTELEM *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
DCTSIZE2 * SIZEOF(DCTELEM)); (DCTSIZE2 * 4) * SIZEOF(DCTELEM));
} }
dtbl = fdct->divisors[qtblno]; dtbl = fdct->divisors[qtblno];
for (i = 0; i < DCTSIZE2; i++) { for (i = 0; i < DCTSIZE2; i++) {
dtbl[i] = ((DCTELEM) qtbl->quantval[jpeg_zigzag_order[i]]) << 3; compute_reciprocal(qtbl->quantval[i] << 3, &dtbl[i]);
} }
break; break;
#endif #endif
@@ -98,7 +247,7 @@ start_pass_fdctmgr (j_compress_ptr cinfo)
*/ */
#define CONST_BITS 14 #define CONST_BITS 14
static const INT16 aanscales[DCTSIZE2] = { static const INT16 aanscales[DCTSIZE2] = {
/* precomputed values scaled up by 14 bits: in natural order */ /* precomputed values scaled up by 14 bits */
16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270, 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270,
21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906, 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906,
@@ -113,14 +262,14 @@ start_pass_fdctmgr (j_compress_ptr cinfo)
if (fdct->divisors[qtblno] == NULL) { if (fdct->divisors[qtblno] == NULL) {
fdct->divisors[qtblno] = (DCTELEM *) fdct->divisors[qtblno] = (DCTELEM *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
DCTSIZE2 * SIZEOF(DCTELEM)); (DCTSIZE2 * 4) * SIZEOF(DCTELEM));
} }
dtbl = fdct->divisors[qtblno]; dtbl = fdct->divisors[qtblno];
for (i = 0; i < DCTSIZE2; i++) { for (i = 0; i < DCTSIZE2; i++) {
dtbl[i] = (DCTELEM) compute_reciprocal(
DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[jpeg_zigzag_order[i]], DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
(INT32) aanscales[i]), (INT32) aanscales[i]),
CONST_BITS-3); CONST_BITS-3), &dtbl[i]);
} }
} }
break; break;
@@ -153,7 +302,7 @@ start_pass_fdctmgr (j_compress_ptr cinfo)
for (row = 0; row < DCTSIZE; row++) { for (row = 0; row < DCTSIZE; row++) {
for (col = 0; col < DCTSIZE; col++) { for (col = 0; col < DCTSIZE; col++) {
fdtbl[i] = (FAST_FLOAT) fdtbl[i] = (FAST_FLOAT)
(1.0 / (((double) qtbl->quantval[jpeg_zigzag_order[i]] * (1.0 / (((double) qtbl->quantval[i] *
aanscalefactor[row] * aanscalefactor[col] * 8.0))); aanscalefactor[row] * aanscalefactor[col] * 8.0)));
i++; i++;
} }
@@ -169,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. * Perform forward DCT on one or more blocks of a component.
* *
@@ -177,7 +397,7 @@ start_pass_fdctmgr (j_compress_ptr cinfo)
* blocks. The quantized coefficients are returned in coef_blocks[]. * blocks. The quantized coefficients are returned in coef_blocks[].
*/ */
METHODDEF void METHODDEF(void)
forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr, forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY sample_data, JBLOCKROW coef_blocks, JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
JDIMENSION start_row, JDIMENSION start_col, JDIMENSION start_row, JDIMENSION start_col,
@@ -186,88 +406,88 @@ forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
{ {
/* This routine is heavily used, so it's worth coding it tightly. */ /* This routine is heavily used, so it's worth coding it tightly. */
my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct; 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 * divisors = fdct->divisors[compptr->quant_tbl_no];
DCTELEM workspace[DCTSIZE2]; /* work area for FDCT subroutine */ DCTELEM * workspace;
JDIMENSION bi; 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 */ sample_data += start_row; /* fold in the vertical offset once */
for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) { for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
/* Load data into workspace, applying unsigned->signed conversion */ /* Load data into workspace, applying unsigned->signed conversion */
{ register DCTELEM *workspaceptr; (*do_convsamp) (sample_data, start_col, workspace);
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
}
}
/* Perform the DCT */ /* Perform the DCT */
(*do_dct) (workspace); (*do_dct) (workspace);
/* Quantize/descale the coefficients, and store into coef_blocks[] */ /* Quantize/descale the coefficients, and store into coef_blocks[] */
{ register DCTELEM temp, qval; (*do_quantize) (coef_blocks[bi], divisors, workspace);
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;
}
}
} }
} }
#ifdef DCT_FLOAT_SUPPORTED #ifdef DCT_FLOAT_SUPPORTED
METHODDEF void
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, forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY sample_data, JBLOCKROW coef_blocks, JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
JDIMENSION start_row, JDIMENSION start_col, JDIMENSION start_row, JDIMENSION start_col,
@@ -276,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. */ /* This routine is heavily used, so it's worth coding it tightly. */
my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct; 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 * divisors = fdct->float_divisors[compptr->quant_tbl_no];
FAST_FLOAT workspace[DCTSIZE2]; /* work area for FDCT subroutine */ FAST_FLOAT * workspace;
JDIMENSION bi; 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 */ sample_data += start_row; /* fold in the vertical offset once */
for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) { for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
/* Load data into workspace, applying unsigned->signed conversion */ /* Load data into workspace, applying unsigned->signed conversion */
{ register FAST_FLOAT *workspaceptr; (*do_convsamp) (sample_data, start_col, workspace);
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
}
}
/* Perform the DCT */ /* Perform the DCT */
(*do_dct) (workspace); (*do_dct) (workspace);
/* Quantize/descale the coefficients, and store into coef_blocks[] */ /* Quantize/descale the coefficients, and store into coef_blocks[] */
{ register FAST_FLOAT temp; (*do_quantize) (coef_blocks[bi], divisors, workspace);
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);
}
}
} }
} }
@@ -342,7 +528,7 @@ forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
* Initialize FDCT manager. * Initialize FDCT manager.
*/ */
GLOBAL void GLOBAL(void)
jinit_forward_dct (j_compress_ptr cinfo) jinit_forward_dct (j_compress_ptr cinfo)
{ {
my_fdct_ptr fdct; my_fdct_ptr fdct;
@@ -354,23 +540,33 @@ jinit_forward_dct (j_compress_ptr cinfo)
cinfo->fdct = (struct jpeg_forward_dct *) fdct; cinfo->fdct = (struct jpeg_forward_dct *) fdct;
fdct->pub.start_pass = start_pass_fdctmgr; fdct->pub.start_pass = start_pass_fdctmgr;
/* First determine the DCT... */
switch (cinfo->dct_method) { switch (cinfo->dct_method) {
#ifdef DCT_ISLOW_SUPPORTED #ifdef DCT_ISLOW_SUPPORTED
case JDCT_ISLOW: case JDCT_ISLOW:
fdct->pub.forward_DCT = forward_DCT; 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; break;
#endif #endif
#ifdef DCT_IFAST_SUPPORTED #ifdef DCT_IFAST_SUPPORTED
case JDCT_IFAST: case JDCT_IFAST:
fdct->pub.forward_DCT = forward_DCT; 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; break;
#endif #endif
#ifdef DCT_FLOAT_SUPPORTED #ifdef DCT_FLOAT_SUPPORTED
case JDCT_FLOAT: case JDCT_FLOAT:
fdct->pub.forward_DCT = forward_DCT_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; break;
#endif #endif
default: default:
@@ -378,6 +574,54 @@ jinit_forward_dct (j_compress_ptr cinfo)
break; 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 */ /* Mark divisor tables unallocated */
for (i = 0; i < NUM_QUANT_TBLS; i++) { for (i = 0; i < NUM_QUANT_TBLS; i++) {
fdct->divisors[i] = NULL; fdct->divisors[i] = NULL;

516
jchuff.c
View File

@@ -1,7 +1,7 @@
/* /*
* jchuff.c * jchuff.c
* *
* Copyright (C) 1991-1995, Thomas G. Lane. * Copyright (C) 1991-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * 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. * 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 #define JPEG_INTERNALS
#include "jinclude.h" #include "jinclude.h"
#include "jpeglib.h" #include "jpeglib.h"
#include "jchuff.h" /* Declarations shared with jcphuff.c */ #include "jchuff.h" /* Declarations shared with jcphuff.c */
#include <limits.h>
static unsigned char jpeg_first_bit_table[65536];
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. /* Expanded entropy encoder object for Huffman encoding.
* *
@@ -27,7 +49,7 @@
*/ */
typedef struct { typedef struct {
INT32 put_buffer; /* current bit-accumulation buffer */ long put_buffer; /* current bit-accumulation buffer */
int put_bits; /* # of bits now in it */ int put_bits; /* # of bits now in it */
int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
} savable_state; } savable_state;
@@ -86,13 +108,13 @@ typedef struct {
/* Forward declarations */ /* Forward declarations */
METHODDEF boolean encode_mcu_huff JPP((j_compress_ptr cinfo, METHODDEF(boolean) encode_mcu_huff JPP((j_compress_ptr cinfo,
JBLOCKROW *MCU_data)); JBLOCKROW *MCU_data));
METHODDEF void finish_pass_huff JPP((j_compress_ptr cinfo)); METHODDEF(void) finish_pass_huff JPP((j_compress_ptr cinfo));
#ifdef ENTROPY_OPT_SUPPORTED #ifdef ENTROPY_OPT_SUPPORTED
METHODDEF boolean encode_mcu_gather JPP((j_compress_ptr cinfo, METHODDEF(boolean) encode_mcu_gather JPP((j_compress_ptr cinfo,
JBLOCKROW *MCU_data)); JBLOCKROW *MCU_data));
METHODDEF void finish_pass_gather JPP((j_compress_ptr cinfo)); METHODDEF(void) finish_pass_gather JPP((j_compress_ptr cinfo));
#endif #endif
@@ -102,7 +124,7 @@ METHODDEF void finish_pass_gather JPP((j_compress_ptr cinfo));
* just count the Huffman symbols used and generate Huffman code tables. * just count the Huffman symbols used and generate Huffman code tables.
*/ */
METHODDEF void METHODDEF(void)
start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics) start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics)
{ {
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
@@ -125,16 +147,14 @@ start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics)
compptr = cinfo->cur_comp_info[ci]; compptr = cinfo->cur_comp_info[ci];
dctbl = compptr->dc_tbl_no; dctbl = compptr->dc_tbl_no;
actbl = compptr->ac_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) { if (gather_statistics) {
#ifdef ENTROPY_OPT_SUPPORTED #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 */ /* Allocate and zero the statistics tables */
/* Note that jpeg_gen_optimal_table expects 257 entries in each table! */ /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */
if (entropy->dc_count_ptrs[dctbl] == NULL) if (entropy->dc_count_ptrs[dctbl] == NULL)
@@ -151,9 +171,9 @@ start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics)
} else { } else {
/* Compute derived values for Huffman tables */ /* Compute derived values for Huffman tables */
/* We may do this more than once for a table, but it's not expensive */ /* 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]); & 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]); & entropy->ac_derived_tbls[actbl]);
} }
/* Initialize DC predictions to 0 */ /* Initialize DC predictions to 0 */
@@ -161,6 +181,7 @@ start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics)
} }
/* Initialize bit buffer to empty */ /* Initialize bit buffer to empty */
entropy->saved.put_buffer = 0; entropy->saved.put_buffer = 0;
entropy->saved.put_bits = 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. * 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. * Note this is also used by jcphuff.c.
*/ */
GLOBAL void 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) c_derived_tbl ** pdtbl)
{ {
JHUFF_TBL *htbl;
c_derived_tbl *dtbl; c_derived_tbl *dtbl;
int p, i, l, lastp, si; int p, i, l, lastp, si, maxsymbol;
char huffsize[257]; char huffsize[257];
unsigned int huffcode[257]; unsigned int huffcode[257];
unsigned int code; 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. */ /* Allocate a workspace if we haven't already done so. */
if (*pdtbl == NULL) if (*pdtbl == NULL)
*pdtbl = (c_derived_tbl *) *pdtbl = (c_derived_tbl *)
@@ -193,19 +229,21 @@ jpeg_make_c_derived_tbl (j_compress_ptr cinfo, JHUFF_TBL * htbl,
dtbl = *pdtbl; dtbl = *pdtbl;
/* Figure C.1: make table of Huffman code length for each symbol */ /* Figure C.1: make table of Huffman code length for each symbol */
/* Note that this is in code-length order. */
p = 0; p = 0;
for (l = 1; l <= 16; l++) { 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++] = (char) l;
} }
huffsize[p] = 0; huffsize[p] = 0;
lastp = p; lastp = p;
/* Figure C.2: generate the codes themselves */ /* 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; code = 0;
si = huffsize[0]; si = huffsize[0];
p = 0; p = 0;
@@ -214,6 +252,11 @@ jpeg_make_c_derived_tbl (j_compress_ptr cinfo, JHUFF_TBL * htbl,
huffcode[p++] = code; huffcode[p++] = code;
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; code <<= 1;
si++; si++;
} }
@@ -221,14 +264,34 @@ jpeg_make_c_derived_tbl (j_compress_ptr cinfo, JHUFF_TBL * htbl,
/* Figure C.3: generate encoding tables */ /* Figure C.3: generate encoding tables */
/* These are code and size indexed by symbol value */ /* These are code and size indexed by symbol value */
/* Set any codeless symbols to have code length 0; /* Set all codeless symbols to have code length 0;
* this allows emit_bits to detect any attempt to emit such symbols. * 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)); 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++) { for (p = 0; p < lastp; p++) {
dtbl->ehufco[htbl->huffval[p]] = huffcode[p]; i = htbl->huffval[p];
dtbl->ehufsi[htbl->huffval[p]] = huffsize[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;
} }
} }
@@ -243,12 +306,14 @@ jpeg_make_c_derived_tbl (j_compress_ptr cinfo, JHUFF_TBL * htbl,
{ action; } } { action; } }
LOCAL boolean LOCAL(boolean)
dump_buffer (working_state * state) dump_buffer (working_state * state)
/* Empty the output buffer; return TRUE if successful, FALSE if must suspend */ /* Empty the output buffer; return TRUE if successful, FALSE if must suspend */
{ {
struct jpeg_destination_mgr * dest = state->cinfo->dest; struct jpeg_destination_mgr * dest = state->cinfo->dest;
dest->free_in_buffer = state->free_in_buffer;
if (! (*dest->empty_output_buffer) (state->cinfo)) if (! (*dest->empty_output_buffer) (state->cinfo))
return FALSE; return FALSE;
/* After a successful buffer dump, must reset buffer pointers */ /* After a successful buffer dump, must reset buffer pointers */
@@ -266,139 +331,250 @@ dump_buffer (working_state * state)
* between calls, so 24 bits are sufficient. * 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 */ #define EMIT_BYTE() { \
if (size == 0) if (0xFF == (*buffer++ = (unsigned char)(put_buffer >> (put_bits -= 8)))) \
ERREXIT(state->cinfo, JERR_HUFF_MISSING_CODE); *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 */ #define DUMP_BITS_(code, size) { \
put_bits += size; \
while (put_bits >= 8) { put_buffer = (put_buffer << size) | code; \
int c = (int) ((put_buffer >> 16) & 0xFF); if (put_bits > 7) \
while(put_bits > 7) \
emit_byte(state, c, return FALSE); EMIT_BYTE() \
if (c == 0xFF) { /* need to stuff a zero byte? */ }
emit_byte(state, 0, return FALSE);
}
put_buffer <<= 8;
put_bits -= 8;
}
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() \
} \
}
LOCAL boolean #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
#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() \
}
int _max=0;
#if __WORDSIZE==64
#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) flush_bits (working_state * state)
{ {
if (! emit_bits(state, 0x7F, 7)) /* fill any partial byte with ones */ unsigned char _buffer[BUFSIZE], *buffer;
return FALSE; long put_buffer; int put_bits;
int bytes, bytestocopy, 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_buffer = 0; /* and reset bit-buffer to empty */
state->cur.put_bits = 0; state->cur.put_bits = 0;
STORE_BUFFER()
return TRUE; return TRUE;
} }
/* Encode a single block's worth of coefficients */ /* Encode a single block's worth of coefficients */
LOCAL boolean LOCAL(boolean)
encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val, encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val,
c_derived_tbl *dctbl, c_derived_tbl *actbl) c_derived_tbl *dctbl, c_derived_tbl *actbl)
{ {
register int temp, temp2; int temp, temp2;
register int nbits; int nbits;
register int k, r, i; int r, sflag, size, code;
unsigned char _buffer[BUFSIZE], *buffer;
long put_buffer; int put_bits;
int code_0xf0 = actbl->ehufco[0xf0], size_0xf0 = actbl->ehufsi[0xf0];
int bytes, bytestocopy, 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 */ /* Encode the DC coefficient difference per section F.1.2.1 */
temp = temp2 = block[0] - last_dc_val; temp = temp2 = block[0] - last_dc_val;
if (temp < 0) { sflag = temp >> 31;
temp = -temp; /* temp is abs value of input */ temp -= ((temp + temp) & sflag);
/* For a negative input, want temp2 = bitwise complement of abs(input) */ temp2 += sflag;
/* This code assumes we are on a two's complement machine */ nbits = jpeg_first_bit_table[temp];
temp2--; DUMP_VALUE_SLOW(dctbl, nbits, temp2, nbits)
}
/* 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;
/* Encode the AC coefficients per section F.1.2.2 */ /* Encode the AC coefficients per section F.1.2.2 */
r = 0; /* r = run length of zeros */ 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; #define innerloop(order) { \
if (temp < 0) { temp2 = *(JCOEF*)((unsigned char*)block + order); \
temp = -temp; /* temp is abs value of input */ if(temp2 == 0) r++; \
/* This code assumes we are on a two's complement machine */ else { \
temp2--; temp = (JCOEF)temp2; \
} sflag = temp >> 31; \
temp = (temp ^ sflag) - sflag; \
/* Find the number of bits needed for the magnitude of the coefficient */ temp2 += sflag; \
nbits = 1; /* there must be at least one 1 bit */ nbits = jpeg_first_bit_table[temp]; \
while ((temp >>= 1)) for(; r > 15; r -= 16) DUMP_BITS(code_0xf0, size_0xf0) \
nbits++; sflag = (r << 4) + nbits; \
DUMP_VALUE(actbl, sflag, temp2, nbits) \
/* Emit Huffman symbol for run length / number of bits */ r = 0; \
i = (r << 4) + nbits; }}
if (! emit_bits(state, actbl->ehufco[i], actbl->ehufsi[i]))
return FALSE;
/* Emit that number of bits of the value, if positive, */ innerloop(2*1); innerloop(2*8); innerloop(2*16); innerloop(2*9);
/* or the complement of its magnitude, if negative. */ innerloop(2*2); innerloop(2*3); innerloop(2*10); innerloop(2*17);
if (! emit_bits(state, (unsigned int) temp2, nbits)) innerloop(2*24); innerloop(2*32); innerloop(2*25); innerloop(2*18);
return FALSE; innerloop(2*11); innerloop(2*4); innerloop(2*5); innerloop(2*12);
innerloop(2*19); innerloop(2*26); innerloop(2*33); innerloop(2*40);
r = 0; 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 the last coef(s) were zero, emit an end-of-block code */
if (r > 0) if (r > 0) DUMP_SINGLE_VALUE(actbl, 0x0)
if (! emit_bits(state, actbl->ehufco[0], actbl->ehufsi[0]))
return FALSE; state->cur.put_buffer = put_buffer;
state->cur.put_bits = put_bits;
STORE_BUFFER()
return TRUE; return TRUE;
} }
@@ -408,7 +584,7 @@ encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val,
* Emit a restart marker & resynchronize predictions. * Emit a restart marker & resynchronize predictions.
*/ */
LOCAL boolean LOCAL(boolean)
emit_restart (working_state * state, int restart_num) emit_restart (working_state * state, int restart_num)
{ {
int ci; int ci;
@@ -433,7 +609,7 @@ emit_restart (working_state * state, int restart_num)
* Encode and output one MCU's worth of Huffman-compressed coefficients. * Encode and output one MCU's worth of Huffman-compressed coefficients.
*/ */
METHODDEF boolean METHODDEF(boolean)
encode_mcu_huff (j_compress_ptr cinfo, JBLOCKROW *MCU_data) encode_mcu_huff (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
{ {
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
@@ -490,7 +666,7 @@ encode_mcu_huff (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
* Finish up at the end of a Huffman-compressed scan. * Finish up at the end of a Huffman-compressed scan.
*/ */
METHODDEF void METHODDEF(void)
finish_pass_huff (j_compress_ptr cinfo) finish_pass_huff (j_compress_ptr cinfo)
{ {
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
@@ -516,19 +692,12 @@ finish_pass_huff (j_compress_ptr cinfo)
/* /*
* Huffman coding optimization. * Huffman coding optimization.
* *
* This actually is optimization, in the sense that we find the best possible * We first scan the supplied data and count the number of uses of each symbol
* Huffman table(s) for the given data. We first scan the supplied data and * that is to be Huffman-coded. (This process MUST agree with the code above.)
* count the number of uses of each symbol that is to be Huffman-coded. * Then we build a Huffman coding tree for the observed counts.
* (This process must agree with the code above.) Then we build an * Symbols which are not needed at all for the particular image are not
* optimal Huffman coding tree for the observed counts. * assigned any code, which saves space in the DHT marker as well as in
* * the compressed data.
* 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.
*/ */
#ifdef ENTROPY_OPT_SUPPORTED #ifdef ENTROPY_OPT_SUPPORTED
@@ -536,8 +705,8 @@ finish_pass_huff (j_compress_ptr cinfo)
/* Process a single block's worth of coefficients */ /* Process a single block's worth of coefficients */
LOCAL void 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[]) long dc_counts[], long ac_counts[])
{ {
register int temp; register int temp;
@@ -556,6 +725,11 @@ htest_one_block (JCOEFPTR block, int last_dc_val,
nbits++; nbits++;
temp >>= 1; 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 */ /* Count the Huffman symbol for the number of bits */
dc_counts[nbits]++; dc_counts[nbits]++;
@@ -582,6 +756,9 @@ htest_one_block (JCOEFPTR block, int last_dc_val,
nbits = 1; /* there must be at least one 1 bit */ nbits = 1; /* there must be at least one 1 bit */
while ((temp >>= 1)) while ((temp >>= 1))
nbits++; 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 */ /* Count Huffman symbol for run length / number of bits */
ac_counts[(r << 4) + nbits]++; ac_counts[(r << 4) + nbits]++;
@@ -601,7 +778,7 @@ htest_one_block (JCOEFPTR block, int last_dc_val,
* No data is actually output, so no suspension return is possible. * No data is actually output, so no suspension return is possible.
*/ */
METHODDEF boolean METHODDEF(boolean)
encode_mcu_gather (j_compress_ptr cinfo, JBLOCKROW *MCU_data) encode_mcu_gather (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
{ {
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
@@ -623,7 +800,7 @@ encode_mcu_gather (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
ci = cinfo->MCU_membership[blkn]; ci = cinfo->MCU_membership[blkn];
compptr = cinfo->cur_comp_info[ci]; 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->dc_count_ptrs[compptr->dc_tbl_no],
entropy->ac_count_ptrs[compptr->ac_tbl_no]); entropy->ac_count_ptrs[compptr->ac_tbl_no]);
entropy->saved.last_dc_val[ci] = MCU_data[blkn][0][0]; entropy->saved.last_dc_val[ci] = MCU_data[blkn][0][0];
@@ -634,11 +811,34 @@ 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. * 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 GLOBAL(void)
jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]) jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])
{ {
#define MAX_CLEN 32 /* assumed maximum initial code length */ #define MAX_CLEN 32 /* assumed maximum initial code length */
@@ -656,10 +856,10 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])
for (i = 0; i < 257; i++) for (i = 0; i < 257; i++)
others[i] = -1; /* init links to empty */ 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 /* Including the pseudo-symbol 256 in the Huffman procedure guarantees
* that no real symbol is given code-value of all ones, because 256 * 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 */ /* Huffman's basic algorithm to assign optimal code lengths to symbols */
@@ -779,7 +979,7 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])
* Finish up a statistics-gathering pass and create the new Huffman tables. * Finish up a statistics-gathering pass and create the new Huffman tables.
*/ */
METHODDEF void METHODDEF(void)
finish_pass_gather (j_compress_ptr cinfo) finish_pass_gather (j_compress_ptr cinfo)
{ {
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
@@ -824,7 +1024,7 @@ finish_pass_gather (j_compress_ptr cinfo)
* Module initialization routine for Huffman entropy encoding. * Module initialization routine for Huffman entropy encoding.
*/ */
GLOBAL void GLOBAL(void)
jinit_huff_encoder (j_compress_ptr cinfo) jinit_huff_encoder (j_compress_ptr cinfo)
{ {
huff_entropy_ptr entropy; huff_entropy_ptr entropy;

View File

@@ -1,7 +1,7 @@
/* /*
* jchuff.h * jchuff.h
* *
* Copyright (C) 1991-1995, Thomas G. Lane. * Copyright (C) 1991-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * 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. * 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 */ /* Derived data constructed for each Huffman table */
typedef struct { typedef struct {
@@ -26,9 +38,10 @@ typedef struct {
#endif /* NEED_SHORT_EXTERNAL_NAMES */ #endif /* NEED_SHORT_EXTERNAL_NAMES */
/* Expand a Huffman table definition into the derived format */ /* Expand a Huffman table definition into the derived format */
EXTERN void jpeg_make_c_derived_tbl JPP((j_compress_ptr cinfo, EXTERN(void) jpeg_make_c_derived_tbl
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 */ /* Generate an optimal table definition given the specified counts */
EXTERN void jpeg_gen_optimal_table JPP((j_compress_ptr cinfo, EXTERN(void) jpeg_gen_optimal_table
JHUFF_TBL * htbl, long freq[])); JPP((j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]));

View File

@@ -1,7 +1,7 @@
/* /*
* jcinit.c * jcinit.c
* *
* Copyright (C) 1991-1995, Thomas G. Lane. * Copyright (C) 1991-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -26,7 +26,7 @@
* which modules will be used and give them appropriate initialization calls. * which modules will be used and give them appropriate initialization calls.
*/ */
GLOBAL void GLOBAL(void)
jinit_compress_master (j_compress_ptr cinfo) jinit_compress_master (j_compress_ptr cinfo)
{ {
/* Initialize master control (includes parameter checking/processing) */ /* Initialize master control (includes parameter checking/processing) */
@@ -56,7 +56,7 @@ jinit_compress_master (j_compress_ptr cinfo)
/* Need a full-image coefficient buffer in any multi-pass mode. */ /* Need a full-image coefficient buffer in any multi-pass mode. */
jinit_c_coef_controller(cinfo, 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_c_main_controller(cinfo, FALSE /* never need full buffer here */);
jinit_marker_writer(cinfo); jinit_marker_writer(cinfo);

View File

@@ -1,7 +1,7 @@
/* /*
* jcmainct.c * jcmainct.c
* *
* Copyright (C) 1994-1995, Thomas G. Lane. * Copyright (C) 1994-1996, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -51,11 +51,11 @@ typedef my_main_controller * my_main_ptr;
/* Forward declarations */ /* Forward declarations */
METHODDEF void process_data_simple_main METHODDEF(void) process_data_simple_main
JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf, JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf,
JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail)); JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail));
#ifdef FULL_MAIN_BUFFER_SUPPORTED #ifdef FULL_MAIN_BUFFER_SUPPORTED
METHODDEF void process_data_buffer_main METHODDEF(void) process_data_buffer_main
JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf, JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf,
JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail)); JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail));
#endif #endif
@@ -65,7 +65,7 @@ METHODDEF void process_data_buffer_main
* Initialize for a processing pass. * Initialize for a processing pass.
*/ */
METHODDEF void METHODDEF(void)
start_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode) start_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
{ {
my_main_ptr main = (my_main_ptr) cinfo->main; my_main_ptr main = (my_main_ptr) cinfo->main;
@@ -109,7 +109,7 @@ start_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
* where we have only a strip buffer. * where we have only a strip buffer.
*/ */
METHODDEF void METHODDEF(void)
process_data_simple_main (j_compress_ptr cinfo, process_data_simple_main (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
JDIMENSION in_rows_avail) JDIMENSION in_rows_avail)
@@ -165,7 +165,7 @@ process_data_simple_main (j_compress_ptr cinfo,
* This routine handles all of the modes that use a full-size buffer. * This routine handles all of the modes that use a full-size buffer.
*/ */
METHODDEF void METHODDEF(void)
process_data_buffer_main (j_compress_ptr cinfo, process_data_buffer_main (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
JDIMENSION in_rows_avail) JDIMENSION in_rows_avail)
@@ -241,7 +241,7 @@ process_data_buffer_main (j_compress_ptr cinfo,
* Initialize main buffer controller. * Initialize main buffer controller.
*/ */
GLOBAL void GLOBAL(void)
jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer) jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer)
{ {
my_main_ptr main; my_main_ptr main;

View File

@@ -1,7 +1,7 @@
/* /*
* jcmarker.c * jcmarker.c
* *
* Copyright (C) 1991-1995, Thomas G. Lane. * Copyright (C) 1991-1998, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -81,6 +81,17 @@ typedef enum { /* JPEG marker codes */
} JPEG_MARKER; } 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. * Basic output routines.
* *
@@ -93,7 +104,7 @@ typedef enum { /* JPEG marker codes */
* points where markers will be written. * points where markers will be written.
*/ */
LOCAL void LOCAL(void)
emit_byte (j_compress_ptr cinfo, int val) emit_byte (j_compress_ptr cinfo, int val)
/* Emit a byte */ /* Emit a byte */
{ {
@@ -107,7 +118,7 @@ emit_byte (j_compress_ptr cinfo, int val)
} }
LOCAL void LOCAL(void)
emit_marker (j_compress_ptr cinfo, JPEG_MARKER mark) emit_marker (j_compress_ptr cinfo, JPEG_MARKER mark)
/* Emit a marker code */ /* Emit a marker code */
{ {
@@ -116,7 +127,7 @@ emit_marker (j_compress_ptr cinfo, JPEG_MARKER mark)
} }
LOCAL void LOCAL(void)
emit_2bytes (j_compress_ptr cinfo, int value) emit_2bytes (j_compress_ptr cinfo, int value)
/* Emit a 2-byte integer; these are always MSB first in JPEG files */ /* Emit a 2-byte integer; these are always MSB first in JPEG files */
{ {
@@ -129,7 +140,7 @@ emit_2bytes (j_compress_ptr cinfo, int value)
* Routines to write specific marker types. * Routines to write specific marker types.
*/ */
LOCAL int LOCAL(int)
emit_dqt (j_compress_ptr cinfo, int index) emit_dqt (j_compress_ptr cinfo, int index)
/* Emit a DQT marker */ /* Emit a DQT marker */
/* Returns the precision used (0 = 8bits, 1 = 16bits) for baseline checking */ /* Returns the precision used (0 = 8bits, 1 = 16bits) for baseline checking */
@@ -155,9 +166,11 @@ emit_dqt (j_compress_ptr cinfo, int index)
emit_byte(cinfo, index + (prec<<4)); emit_byte(cinfo, index + (prec<<4));
for (i = 0; i < DCTSIZE2; i++) { for (i = 0; i < DCTSIZE2; i++) {
/* The table entries must be emitted in zigzag order. */
unsigned int qval = qtbl->quantval[jpeg_natural_order[i]];
if (prec) if (prec)
emit_byte(cinfo, qtbl->quantval[i] >> 8); emit_byte(cinfo, (int) (qval >> 8));
emit_byte(cinfo, qtbl->quantval[i] & 0xFF); emit_byte(cinfo, (int) (qval & 0xFF));
} }
qtbl->sent_table = TRUE; qtbl->sent_table = TRUE;
@@ -167,7 +180,7 @@ emit_dqt (j_compress_ptr cinfo, int index)
} }
LOCAL void LOCAL(void)
emit_dht (j_compress_ptr cinfo, int index, boolean is_ac) emit_dht (j_compress_ptr cinfo, int index, boolean is_ac)
/* Emit a DHT marker */ /* Emit a DHT marker */
{ {
@@ -205,7 +218,7 @@ emit_dht (j_compress_ptr cinfo, int index, boolean is_ac)
} }
LOCAL void LOCAL(void)
emit_dac (j_compress_ptr cinfo) emit_dac (j_compress_ptr cinfo)
/* Emit a DAC marker */ /* Emit a DAC marker */
/* Since the useful info is so small, we want to emit all the tables in */ /* Since the useful info is so small, we want to emit all the tables in */
@@ -248,7 +261,7 @@ emit_dac (j_compress_ptr cinfo)
} }
LOCAL void LOCAL(void)
emit_dri (j_compress_ptr cinfo) emit_dri (j_compress_ptr cinfo)
/* Emit a DRI marker */ /* Emit a DRI marker */
{ {
@@ -260,7 +273,7 @@ emit_dri (j_compress_ptr cinfo)
} }
LOCAL void LOCAL(void)
emit_sof (j_compress_ptr cinfo, JPEG_MARKER code) emit_sof (j_compress_ptr cinfo, JPEG_MARKER code)
/* Emit a SOF marker */ /* Emit a SOF marker */
{ {
@@ -291,7 +304,7 @@ emit_sof (j_compress_ptr cinfo, JPEG_MARKER code)
} }
LOCAL void LOCAL(void)
emit_sos (j_compress_ptr cinfo) emit_sos (j_compress_ptr cinfo)
/* Emit a SOS marker */ /* Emit a SOS marker */
{ {
@@ -332,7 +345,7 @@ emit_sos (j_compress_ptr cinfo)
} }
LOCAL void LOCAL(void)
emit_jfif_app0 (j_compress_ptr cinfo) emit_jfif_app0 (j_compress_ptr cinfo)
/* Emit a JFIF-compliant APP0 marker */ /* Emit a JFIF-compliant APP0 marker */
{ {
@@ -340,7 +353,7 @@ emit_jfif_app0 (j_compress_ptr cinfo)
* Length of APP0 block (2 bytes) * Length of APP0 block (2 bytes)
* Block ID (4 bytes - ASCII "JFIF") * Block ID (4 bytes - ASCII "JFIF")
* Zero byte (1 byte to terminate the ID string) * 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) * Units (1 byte - 0x00 = none, 0x01 = inch, 0x02 = cm)
* Xdpu (2 bytes - dots per unit horizontal) * Xdpu (2 bytes - dots per unit horizontal)
* Ydpu (2 bytes - dots per unit vertical) * Ydpu (2 bytes - dots per unit vertical)
@@ -357,11 +370,8 @@ emit_jfif_app0 (j_compress_ptr cinfo)
emit_byte(cinfo, 0x49); emit_byte(cinfo, 0x49);
emit_byte(cinfo, 0x46); emit_byte(cinfo, 0x46);
emit_byte(cinfo, 0); emit_byte(cinfo, 0);
/* We currently emit version code 1.01 since we use no 1.02 features. emit_byte(cinfo, cinfo->JFIF_major_version); /* Version fields */
* This may avoid complaints from some older decoders. emit_byte(cinfo, cinfo->JFIF_minor_version);
*/
emit_byte(cinfo, 1); /* Major version */
emit_byte(cinfo, 1); /* Minor version */
emit_byte(cinfo, cinfo->density_unit); /* Pixel size information */ emit_byte(cinfo, cinfo->density_unit); /* Pixel size information */
emit_2bytes(cinfo, (int) cinfo->X_density); emit_2bytes(cinfo, (int) cinfo->X_density);
emit_2bytes(cinfo, (int) cinfo->Y_density); emit_2bytes(cinfo, (int) cinfo->Y_density);
@@ -370,7 +380,7 @@ emit_jfif_app0 (j_compress_ptr cinfo)
} }
LOCAL void LOCAL(void)
emit_adobe_app14 (j_compress_ptr cinfo) emit_adobe_app14 (j_compress_ptr cinfo)
/* Emit an Adobe APP14 marker */ /* Emit an Adobe APP14 marker */
{ {
@@ -417,28 +427,30 @@ emit_adobe_app14 (j_compress_ptr cinfo)
/* /*
* This routine is exported for possible use by applications. * These routines allow writing an arbitrary marker with parameters.
* The intended use is to emit COM or APPn markers after calling * The only intended use is to emit COM or APPn markers after calling
* jpeg_start_compress() and before the first jpeg_write_scanlines() call * write_file_header and before calling write_frame_header.
* (hence, after write_file_header but before write_frame_header).
* Other uses are not guaranteed to produce desirable results. * Other uses are not guaranteed to produce desirable results.
* Counting the parameter bytes properly is the caller's responsibility.
*/ */
METHODDEF void METHODDEF(void)
write_any_marker (j_compress_ptr cinfo, int marker, write_marker_header (j_compress_ptr cinfo, int marker, unsigned int datalen)
const JOCTET *dataptr, unsigned int datalen) /* Emit an arbitrary marker header */
/* Emit an arbitrary marker with parameters */
{ {
if (datalen <= (unsigned int) 65533) { /* safety check */ if (datalen > (unsigned int) 65533) /* safety check */
emit_marker(cinfo, (JPEG_MARKER) marker); ERREXIT(cinfo, JERR_BAD_LENGTH);
emit_2bytes(cinfo, (int) (datalen + 2)); /* total length */
while (datalen--) { emit_marker(cinfo, (JPEG_MARKER) marker);
emit_byte(cinfo, *dataptr);
dataptr++; 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);
} }
@@ -453,11 +465,16 @@ write_any_marker (j_compress_ptr cinfo, int marker,
* jpeg_start_compress returns. * jpeg_start_compress returns.
*/ */
METHODDEF void METHODDEF(void)
write_file_header (j_compress_ptr cinfo) write_file_header (j_compress_ptr cinfo)
{ {
my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
emit_marker(cinfo, M_SOI); /* first the SOI */ 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 */ if (cinfo->write_JFIF_header) /* next an optional JFIF APP0 */
emit_jfif_app0(cinfo); emit_jfif_app0(cinfo);
if (cinfo->write_Adobe_marker) /* next an optional Adobe APP14 */ if (cinfo->write_Adobe_marker) /* next an optional Adobe APP14 */
@@ -473,7 +490,7 @@ write_file_header (j_compress_ptr cinfo)
* try to error-check the quant table numbers as soon as they see the SOF. * try to error-check the quant table numbers as soon as they see the SOF.
*/ */
METHODDEF void METHODDEF(void)
write_frame_header (j_compress_ptr cinfo) write_frame_header (j_compress_ptr cinfo)
{ {
int ci, prec; int ci, prec;
@@ -530,9 +547,10 @@ write_frame_header (j_compress_ptr cinfo)
* Compressed data will be written following the SOS. * Compressed data will be written following the SOS.
*/ */
METHODDEF void METHODDEF(void)
write_scan_header (j_compress_ptr cinfo) write_scan_header (j_compress_ptr cinfo)
{ {
my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
int i; int i;
jpeg_component_info *compptr; jpeg_component_info *compptr;
@@ -565,11 +583,12 @@ write_scan_header (j_compress_ptr cinfo)
} }
/* Emit DRI if required --- note that DRI value could change for each scan. /* 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 avoid wasting space with unnecessary DRIs, however.
* We assume DRI will never be nonzero for one scan and zero for a later one.
*/ */
if (cinfo->restart_interval) if (cinfo->restart_interval != marker->last_restart_interval) {
emit_dri(cinfo); emit_dri(cinfo);
marker->last_restart_interval = cinfo->restart_interval;
}
emit_sos(cinfo); emit_sos(cinfo);
} }
@@ -579,7 +598,7 @@ write_scan_header (j_compress_ptr cinfo)
* Write datastream trailer. * Write datastream trailer.
*/ */
METHODDEF void METHODDEF(void)
write_file_trailer (j_compress_ptr cinfo) write_file_trailer (j_compress_ptr cinfo)
{ {
emit_marker(cinfo, M_EOI); emit_marker(cinfo, M_EOI);
@@ -593,7 +612,7 @@ write_file_trailer (j_compress_ptr cinfo)
* emitted. Note that all tables will be marked sent_table = TRUE at exit. * emitted. Note that all tables will be marked sent_table = TRUE at exit.
*/ */
METHODDEF void METHODDEF(void)
write_tables_only (j_compress_ptr cinfo) write_tables_only (j_compress_ptr cinfo)
{ {
int i; int i;
@@ -622,18 +641,24 @@ write_tables_only (j_compress_ptr cinfo)
* Initialize the marker writer module. * Initialize the marker writer module.
*/ */
GLOBAL void GLOBAL(void)
jinit_marker_writer (j_compress_ptr cinfo) jinit_marker_writer (j_compress_ptr cinfo)
{ {
my_marker_ptr marker;
/* Create the subobject */ /* Create the subobject */
cinfo->marker = (struct jpeg_marker_writer *) marker = (my_marker_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, (*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 */ /* Initialize method pointers */
cinfo->marker->write_any_marker = write_any_marker; marker->pub.write_file_header = write_file_header;
cinfo->marker->write_file_header = write_file_header; marker->pub.write_frame_header = write_frame_header;
cinfo->marker->write_frame_header = write_frame_header; marker->pub.write_scan_header = write_scan_header;
cinfo->marker->write_scan_header = write_scan_header; marker->pub.write_file_trailer = write_file_trailer;
cinfo->marker->write_file_trailer = write_file_trailer; marker->pub.write_tables_only = write_tables_only;
cinfo->marker->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,7 @@
/* /*
* jcmaster.c * jcmaster.c
* *
* Copyright (C) 1991-1995, Thomas G. Lane. * Copyright (C) 1991-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -42,7 +42,7 @@ typedef my_comp_master * my_master_ptr;
* Support routines that do various essential calculations. * Support routines that do various essential calculations.
*/ */
LOCAL void LOCAL(void)
initial_setup (j_compress_ptr cinfo) initial_setup (j_compress_ptr cinfo)
/* Do computations that are needed before master selection phase */ /* Do computations that are needed before master selection phase */
{ {
@@ -126,7 +126,7 @@ initial_setup (j_compress_ptr cinfo)
#ifdef C_MULTISCAN_FILES_SUPPORTED #ifdef C_MULTISCAN_FILES_SUPPORTED
LOCAL void LOCAL(void)
validate_script (j_compress_ptr cinfo) validate_script (j_compress_ptr cinfo)
/* Verify that the scan script in cinfo->scan_info[] is valid; also /* Verify that the scan script in cinfo->scan_info[] is valid; also
* determine whether it uses progressive JPEG, and set cinfo->progressive_mode. * determine whether it uses progressive JPEG, and set cinfo->progressive_mode.
@@ -185,8 +185,20 @@ validate_script (j_compress_ptr cinfo)
Al = scanptr->Al; Al = scanptr->Al;
if (cinfo->progressive_mode) { if (cinfo->progressive_mode) {
#ifdef C_PROGRESSIVE_SUPPORTED #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 || 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); ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
if (Ss == 0) { if (Ss == 0) {
if (Se != 0) /* DC and AC together not OK */ if (Se != 0) /* DC and AC together not OK */
@@ -251,7 +263,7 @@ validate_script (j_compress_ptr cinfo)
#endif /* C_MULTISCAN_FILES_SUPPORTED */ #endif /* C_MULTISCAN_FILES_SUPPORTED */
LOCAL void LOCAL(void)
select_scan_parameters (j_compress_ptr cinfo) select_scan_parameters (j_compress_ptr cinfo)
/* Set up the scan parameters for the current scan */ /* Set up the scan parameters for the current scan */
{ {
@@ -292,7 +304,7 @@ select_scan_parameters (j_compress_ptr cinfo)
} }
LOCAL void LOCAL(void)
per_scan_setup (j_compress_ptr cinfo) per_scan_setup (j_compress_ptr cinfo)
/* Do computations that are needed before processing a JPEG scan */ /* Do computations that are needed before processing a JPEG scan */
/* cinfo->comps_in_scan and cinfo->cur_comp_info[] are already set */ /* cinfo->comps_in_scan and cinfo->cur_comp_info[] are already set */
@@ -385,7 +397,7 @@ per_scan_setup (j_compress_ptr cinfo)
* required. * required.
*/ */
METHODDEF void METHODDEF(void)
prepare_for_pass (j_compress_ptr cinfo) prepare_for_pass (j_compress_ptr cinfo)
{ {
my_master_ptr master = (my_master_ptr) cinfo->master; my_master_ptr master = (my_master_ptr) cinfo->master;
@@ -473,7 +485,7 @@ prepare_for_pass (j_compress_ptr cinfo)
* In multi-pass processing, this routine is not used. * In multi-pass processing, this routine is not used.
*/ */
METHODDEF void METHODDEF(void)
pass_startup (j_compress_ptr cinfo) pass_startup (j_compress_ptr cinfo)
{ {
cinfo->master->call_pass_startup = FALSE; /* reset flag so call only once */ cinfo->master->call_pass_startup = FALSE; /* reset flag so call only once */
@@ -487,7 +499,7 @@ pass_startup (j_compress_ptr cinfo)
* Finish up at end of pass. * Finish up at end of pass.
*/ */
METHODDEF void METHODDEF(void)
finish_pass_master (j_compress_ptr cinfo) finish_pass_master (j_compress_ptr cinfo)
{ {
my_master_ptr master = (my_master_ptr) cinfo->master; my_master_ptr master = (my_master_ptr) cinfo->master;
@@ -527,7 +539,7 @@ finish_pass_master (j_compress_ptr cinfo)
* Initialize master compression control. * Initialize master compression control.
*/ */
GLOBAL void GLOBAL(void)
jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only) jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only)
{ {
my_master_ptr master; my_master_ptr master;

View File

@@ -1,7 +1,7 @@
/* /*
* jcomapi.c * jcomapi.c
* *
* Copyright (C) 1994, Thomas G. Lane. * Copyright (C) 1994-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -25,11 +25,15 @@
* responsibility. * responsibility.
*/ */
GLOBAL void GLOBAL(void)
jpeg_abort (j_common_ptr cinfo) jpeg_abort (j_common_ptr cinfo)
{ {
int pool; 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 /* Releasing pools in reverse order might help avoid fragmentation
* with some (brain-damaged) malloc libraries. * with some (brain-damaged) malloc libraries.
*/ */
@@ -38,7 +42,15 @@ jpeg_abort (j_common_ptr cinfo)
} }
/* Reset overall state for possible reuse of object */ /* 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;
}
} }
@@ -53,7 +65,7 @@ jpeg_abort (j_common_ptr cinfo)
* responsibility. * responsibility.
*/ */
GLOBAL void GLOBAL(void)
jpeg_destroy (j_common_ptr cinfo) jpeg_destroy (j_common_ptr cinfo)
{ {
/* We need only tell the memory manager to release everything. */ /* We need only tell the memory manager to release everything. */
@@ -70,7 +82,7 @@ jpeg_destroy (j_common_ptr cinfo)
* (Would jutils.c be a more reasonable place to put these?) * (Would jutils.c be a more reasonable place to put these?)
*/ */
GLOBAL JQUANT_TBL * GLOBAL(JQUANT_TBL *)
jpeg_alloc_quant_table (j_common_ptr cinfo) jpeg_alloc_quant_table (j_common_ptr cinfo)
{ {
JQUANT_TBL *tbl; JQUANT_TBL *tbl;
@@ -82,7 +94,7 @@ jpeg_alloc_quant_table (j_common_ptr cinfo)
} }
GLOBAL JHUFF_TBL * GLOBAL(JHUFF_TBL *)
jpeg_alloc_huff_table (j_common_ptr cinfo) jpeg_alloc_huff_table (j_common_ptr cinfo)
{ {
JHUFF_TBL *tbl; JHUFF_TBL *tbl;

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 */

49
jconfig.h.in Normal file
View File

@@ -0,0 +1,49 @@
/* 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,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 */

122
jcparam.c
View File

@@ -1,7 +1,8 @@
/* /*
* jcparam.c * jcparam.c
* *
* Copyright (C) 1991-1995, Thomas G. Lane. * Copyright (C) 1991-1998, Thomas G. Lane.
* Copyright (C) 2009, D. R. Commander.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -19,7 +20,7 @@
* Quantization table setup routines * Quantization table setup routines
*/ */
GLOBAL void GLOBAL(void)
jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl, jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl,
const unsigned int *basic_table, const unsigned int *basic_table,
int scale_factor, boolean force_baseline) int scale_factor, boolean force_baseline)
@@ -29,7 +30,7 @@ jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl,
* are limited to 1..255 for JPEG baseline compatibility. * are limited to 1..255 for JPEG baseline compatibility.
*/ */
{ {
JQUANT_TBL ** qtblptr = & cinfo->quant_tbl_ptrs[which_tbl]; JQUANT_TBL ** qtblptr;
int i; int i;
long temp; long temp;
@@ -37,6 +38,11 @@ jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl,
if (cinfo->global_state != CSTATE_START) if (cinfo->global_state != CSTATE_START)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); 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) if (*qtblptr == NULL)
*qtblptr = jpeg_alloc_quant_table((j_common_ptr) cinfo); *qtblptr = jpeg_alloc_quant_table((j_common_ptr) cinfo);
@@ -55,7 +61,7 @@ jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl,
} }
GLOBAL void GLOBAL(void)
jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor, jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor,
boolean force_baseline) boolean force_baseline)
/* Set or change the 'quality' (quantization) setting, using default tables /* Set or change the 'quality' (quantization) setting, using default tables
@@ -64,31 +70,30 @@ jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor,
* applications that insist on a linear percentage scaling. * applications that insist on a linear percentage scaling.
*/ */
{ {
/* This is the sample quantization table given in the JPEG spec section K.1, /* These are the sample quantization tables given in JPEG spec section K.1.
* but expressed in zigzag order (as are all of our quant. tables).
* The spec says that the values given produce "good" quality, and * The spec says that the values given produce "good" quality, and
* when divided by 2, "very good" quality. * when divided by 2, "very good" quality.
*/ */
static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = { static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = {
16, 11, 12, 14, 12, 10, 16, 14, 16, 11, 10, 16, 24, 40, 51, 61,
13, 14, 18, 17, 16, 19, 24, 40, 12, 12, 14, 19, 26, 58, 60, 55,
26, 24, 22, 22, 24, 49, 35, 37, 14, 13, 16, 24, 40, 57, 69, 56,
29, 40, 58, 51, 61, 60, 57, 51, 14, 17, 22, 29, 51, 87, 80, 62,
56, 55, 64, 72, 92, 78, 64, 68, 18, 22, 37, 56, 68, 109, 103, 77,
87, 69, 55, 56, 80, 109, 81, 87, 24, 35, 55, 64, 81, 104, 113, 92,
95, 98, 103, 104, 103, 62, 77, 113, 49, 64, 78, 87, 103, 121, 120, 101,
121, 112, 100, 120, 92, 101, 103, 99 72, 92, 95, 98, 112, 100, 103, 99
}; };
static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = { static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = {
17, 18, 18, 24, 21, 24, 47, 26, 17, 18, 24, 47, 99, 99, 99, 99,
26, 47, 99, 66, 56, 66, 99, 99, 18, 21, 26, 66, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99, 24, 26, 56, 99, 99, 99, 99, 99,
99, 99, 99, 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,
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 */ /* Set up two quantization tables using the specified scaling */
jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl, jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl,
@@ -98,7 +103,7 @@ jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor,
} }
GLOBAL int GLOBAL(int)
jpeg_quality_scaling (int quality) jpeg_quality_scaling (int quality)
/* Convert a user-specified quality rating to a percentage scaling factor /* Convert a user-specified quality rating to a percentage scaling factor
* for an underlying quantization table, using our recommended scaling curve. * for an underlying quantization table, using our recommended scaling curve.
@@ -111,8 +116,8 @@ jpeg_quality_scaling (int quality)
/* The basic table is used as-is (scaling 100) for a quality of 50. /* The basic table is used as-is (scaling 100) for a quality of 50.
* Qualities 50..100 are converted to scaling percentage 200 - 2*Q; * Qualities 50..100 are converted to scaling percentage 200 - 2*Q;
* note that at Q=100 the scaling is 0, which will cause j_add_quant_table * note that at Q=100 the scaling is 0, which will cause jpeg_add_quant_table
* to make all the table entries 1 (hence, no quantization loss). * to make all the table entries 1 (hence, minimum quantization loss).
* Qualities 1..50 are converted to scaling percentage 5000/Q. * Qualities 1..50 are converted to scaling percentage 5000/Q.
*/ */
if (quality < 50) if (quality < 50)
@@ -124,7 +129,7 @@ jpeg_quality_scaling (int quality)
} }
GLOBAL void GLOBAL(void)
jpeg_set_quality (j_compress_ptr cinfo, int quality, boolean force_baseline) jpeg_set_quality (j_compress_ptr cinfo, int quality, boolean force_baseline)
/* Set or change the 'quality' (quantization) setting, using default tables. /* Set or change the 'quality' (quantization) setting, using default tables.
* This is the standard quality-adjusting entry point for typical user * This is the standard quality-adjusting entry point for typical user
@@ -144,23 +149,37 @@ jpeg_set_quality (j_compress_ptr cinfo, int quality, boolean force_baseline)
* Huffman table setup routines * Huffman table setup routines
*/ */
LOCAL void LOCAL(void)
add_huff_table (j_compress_ptr cinfo, add_huff_table (j_compress_ptr cinfo,
JHUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val) JHUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val)
/* Define a Huffman table */ /* Define a Huffman table */
{ {
int nsymbols, len;
if (*htblptr == NULL) if (*htblptr == NULL)
*htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); *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)->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. */ /* Initialize sent_table FALSE so table will be written to JPEG file. */
(*htblptr)->sent_table = FALSE; (*htblptr)->sent_table = FALSE;
} }
LOCAL void LOCAL(void)
std_huff_tables (j_compress_ptr cinfo) std_huff_tables (j_compress_ptr cinfo)
/* Set up the standard Huffman tables (cf. JPEG standard section K.3) */ /* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
/* IMPORTANT: these are only valid for 8-bit data precision! */ /* IMPORTANT: these are only valid for 8-bit data precision! */
@@ -246,7 +265,7 @@ std_huff_tables (j_compress_ptr cinfo)
* your code will still work (they'll be set to reasonable defaults). * your code will still work (they'll be set to reasonable defaults).
*/ */
GLOBAL void GLOBAL(void)
jpeg_set_defaults (j_compress_ptr cinfo) jpeg_set_defaults (j_compress_ptr cinfo)
{ {
int i; int i;
@@ -314,7 +333,15 @@ jpeg_set_defaults (j_compress_ptr cinfo)
/* Fill in default JFIF marker parameters. Note that whether the marker /* Fill in default JFIF marker parameters. Note that whether the marker
* will actually be written is determined by jpeg_set_colorspace. * 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->density_unit = 0; /* Pixel size is unknown by default */
cinfo->X_density = 1; /* Pixel aspect ratio is square by default */ cinfo->X_density = 1; /* Pixel aspect ratio is square by default */
cinfo->Y_density = 1; cinfo->Y_density = 1;
@@ -329,7 +356,7 @@ jpeg_set_defaults (j_compress_ptr cinfo)
* Select an appropriate JPEG colorspace for in_color_space. * Select an appropriate JPEG colorspace for in_color_space.
*/ */
GLOBAL void GLOBAL(void)
jpeg_default_colorspace (j_compress_ptr cinfo) jpeg_default_colorspace (j_compress_ptr cinfo)
{ {
switch (cinfo->in_color_space) { switch (cinfo->in_color_space) {
@@ -337,6 +364,12 @@ jpeg_default_colorspace (j_compress_ptr cinfo)
jpeg_set_colorspace(cinfo, JCS_GRAYSCALE); jpeg_set_colorspace(cinfo, JCS_GRAYSCALE);
break; break;
case JCS_RGB: 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); jpeg_set_colorspace(cinfo, JCS_YCbCr);
break; break;
case JCS_YCbCr: case JCS_YCbCr:
@@ -361,7 +394,7 @@ jpeg_default_colorspace (j_compress_ptr cinfo)
* Set the JPEG colorspace, and choose colorspace-dependent default values. * Set the JPEG colorspace, and choose colorspace-dependent default values.
*/ */
GLOBAL void GLOBAL(void)
jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace) jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace)
{ {
jpeg_component_info * compptr; jpeg_component_info * compptr;
@@ -445,7 +478,7 @@ jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace)
#ifdef C_PROGRESSIVE_SUPPORTED #ifdef C_PROGRESSIVE_SUPPORTED
LOCAL jpeg_scan_info * LOCAL(jpeg_scan_info *)
fill_a_scan (jpeg_scan_info * scanptr, int ci, fill_a_scan (jpeg_scan_info * scanptr, int ci,
int Ss, int Se, int Ah, int Al) int Ss, int Se, int Ah, int Al)
/* Support routine: generate one scan for specified component */ /* Support routine: generate one scan for specified component */
@@ -460,7 +493,7 @@ fill_a_scan (jpeg_scan_info * scanptr, int ci,
return scanptr; return scanptr;
} }
LOCAL jpeg_scan_info * LOCAL(jpeg_scan_info *)
fill_scans (jpeg_scan_info * scanptr, int ncomps, fill_scans (jpeg_scan_info * scanptr, int ncomps,
int Ss, int Se, int Ah, int Al) int Ss, int Se, int Ah, int Al)
/* Support routine: generate one scan for each component */ /* Support routine: generate one scan for each component */
@@ -479,7 +512,7 @@ fill_scans (jpeg_scan_info * scanptr, int ncomps,
return scanptr; return scanptr;
} }
LOCAL jpeg_scan_info * LOCAL(jpeg_scan_info *)
fill_dc_scans (jpeg_scan_info * scanptr, int ncomps, int Ah, int Al) fill_dc_scans (jpeg_scan_info * scanptr, int ncomps, int Ah, int Al)
/* Support routine: generate interleaved DC scan if possible, else N scans */ /* Support routine: generate interleaved DC scan if possible, else N scans */
{ {
@@ -507,7 +540,7 @@ fill_dc_scans (jpeg_scan_info * scanptr, int ncomps, int Ah, int Al)
* cinfo->num_components and cinfo->jpeg_color_space must be correct. * cinfo->num_components and cinfo->jpeg_color_space must be correct.
*/ */
GLOBAL void GLOBAL(void)
jpeg_simple_progression (j_compress_ptr cinfo) jpeg_simple_progression (j_compress_ptr cinfo)
{ {
int ncomps = cinfo->num_components; int ncomps = cinfo->num_components;
@@ -530,11 +563,20 @@ jpeg_simple_progression (j_compress_ptr cinfo)
nscans = 2 + 4 * ncomps; /* 2 DC scans; 4 AC scans per component */ nscans = 2 + 4 * ncomps; /* 2 DC scans; 4 AC scans per component */
} }
/* Allocate space for script. */ /* Allocate space for script.
/* We use permanent pool just in case application re-uses script. */ * We need to put it in the permanent pool in case the application performs
scanptr = (jpeg_scan_info *) * multiple compressions without changing the settings. To avoid a memory
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, * leak if jpeg_simple_progression is called repeatedly for the same JPEG
nscans * SIZEOF(jpeg_scan_info)); * 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->scan_info = scanptr;
cinfo->num_scans = nscans; cinfo->num_scans = nscans;

View File

@@ -1,7 +1,7 @@
/* /*
* jcphuff.c * jcphuff.c
* *
* Copyright (C) 1995, Thomas G. Lane. * Copyright (C) 1995-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -86,23 +86,23 @@ typedef phuff_entropy_encoder * phuff_entropy_ptr;
#endif #endif
/* Forward declarations */ /* Forward declarations */
METHODDEF boolean encode_mcu_DC_first JPP((j_compress_ptr cinfo, METHODDEF(boolean) encode_mcu_DC_first JPP((j_compress_ptr cinfo,
JBLOCKROW *MCU_data));
METHODDEF boolean encode_mcu_AC_first JPP((j_compress_ptr cinfo,
JBLOCKROW *MCU_data));
METHODDEF boolean encode_mcu_DC_refine JPP((j_compress_ptr cinfo,
JBLOCKROW *MCU_data)); JBLOCKROW *MCU_data));
METHODDEF boolean encode_mcu_AC_refine JPP((j_compress_ptr cinfo, METHODDEF(boolean) encode_mcu_AC_first JPP((j_compress_ptr cinfo,
JBLOCKROW *MCU_data)); JBLOCKROW *MCU_data));
METHODDEF void finish_pass_phuff JPP((j_compress_ptr cinfo)); METHODDEF(boolean) encode_mcu_DC_refine JPP((j_compress_ptr cinfo,
METHODDEF void finish_pass_gather_phuff JPP((j_compress_ptr cinfo)); JBLOCKROW *MCU_data));
METHODDEF(boolean) encode_mcu_AC_refine JPP((j_compress_ptr cinfo,
JBLOCKROW *MCU_data));
METHODDEF(void) finish_pass_phuff JPP((j_compress_ptr cinfo));
METHODDEF(void) finish_pass_gather_phuff JPP((j_compress_ptr cinfo));
/* /*
* Initialize for a Huffman-compressed scan using progressive JPEG. * Initialize for a Huffman-compressed scan using progressive JPEG.
*/ */
METHODDEF void METHODDEF(void)
start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics) start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics)
{ {
phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
@@ -147,22 +147,19 @@ start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics)
compptr = cinfo->cur_comp_info[ci]; compptr = cinfo->cur_comp_info[ci];
/* Initialize DC predictions to 0 */ /* Initialize DC predictions to 0 */
entropy->last_dc_val[ci] = 0; entropy->last_dc_val[ci] = 0;
/* Make sure requested tables are present */ /* Get table index */
/* (In gather mode, tables need not be allocated yet) */
if (is_DC_band) { if (is_DC_band) {
if (cinfo->Ah != 0) /* DC refinement needs no table */ if (cinfo->Ah != 0) /* DC refinement needs no table */
continue; continue;
tbl = compptr->dc_tbl_no; 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 { } else {
entropy->ac_tbl_no = tbl = compptr->ac_tbl_no; 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) { 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 */ /* Allocate and zero the statistics tables */
/* Note that jpeg_gen_optimal_table expects 257 entries in each table! */ /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */
if (entropy->count_ptrs[tbl] == NULL) if (entropy->count_ptrs[tbl] == NULL)
@@ -171,14 +168,10 @@ start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics)
257 * SIZEOF(long)); 257 * SIZEOF(long));
MEMZERO(entropy->count_ptrs[tbl], 257 * SIZEOF(long)); MEMZERO(entropy->count_ptrs[tbl], 257 * SIZEOF(long));
} else { } 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 */ /* 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, is_DC_band, tbl,
jpeg_make_c_derived_tbl(cinfo, cinfo->dc_huff_tbl_ptrs[tbl], & entropy->derived_tbls[tbl]);
& entropy->derived_tbls[tbl]);
else
jpeg_make_c_derived_tbl(cinfo, cinfo->ac_huff_tbl_ptrs[tbl],
& entropy->derived_tbls[tbl]);
} }
} }
@@ -208,7 +201,7 @@ start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics)
dump_buffer(entropy); } dump_buffer(entropy); }
LOCAL void LOCAL(void)
dump_buffer (phuff_entropy_ptr entropy) dump_buffer (phuff_entropy_ptr entropy)
/* Empty the output buffer; we do not support suspension in this module. */ /* Empty the output buffer; we do not support suspension in this module. */
{ {
@@ -230,8 +223,7 @@ dump_buffer (phuff_entropy_ptr entropy)
* between calls, so 24 bits are sufficient. * between calls, so 24 bits are sufficient.
*/ */
INLINE LOCAL(void)
LOCAL void
emit_bits (phuff_entropy_ptr entropy, unsigned int code, int size) emit_bits (phuff_entropy_ptr entropy, unsigned int code, int size)
/* Emit some bits, unless we are in gather mode */ /* Emit some bits, unless we are in gather mode */
{ {
@@ -270,7 +262,7 @@ emit_bits (phuff_entropy_ptr entropy, unsigned int code, int size)
} }
LOCAL void LOCAL(void)
flush_bits (phuff_entropy_ptr entropy) flush_bits (phuff_entropy_ptr entropy)
{ {
emit_bits(entropy, 0x7F, 7); /* fill any partial byte with ones */ emit_bits(entropy, 0x7F, 7); /* fill any partial byte with ones */
@@ -283,8 +275,7 @@ flush_bits (phuff_entropy_ptr entropy)
* Emit (or just count) a Huffman symbol. * Emit (or just count) a Huffman symbol.
*/ */
INLINE LOCAL(void)
LOCAL void
emit_symbol (phuff_entropy_ptr entropy, int tbl_no, int symbol) emit_symbol (phuff_entropy_ptr entropy, int tbl_no, int symbol)
{ {
if (entropy->gather_statistics) if (entropy->gather_statistics)
@@ -300,7 +291,7 @@ emit_symbol (phuff_entropy_ptr entropy, int tbl_no, int symbol)
* Emit bits from a correction bit buffer. * Emit bits from a correction bit buffer.
*/ */
LOCAL void LOCAL(void)
emit_buffered_bits (phuff_entropy_ptr entropy, char * bufstart, emit_buffered_bits (phuff_entropy_ptr entropy, char * bufstart,
unsigned int nbits) unsigned int nbits)
{ {
@@ -319,7 +310,7 @@ emit_buffered_bits (phuff_entropy_ptr entropy, char * bufstart,
* Emit any pending EOBRUN symbol. * Emit any pending EOBRUN symbol.
*/ */
LOCAL void LOCAL(void)
emit_eobrun (phuff_entropy_ptr entropy) emit_eobrun (phuff_entropy_ptr entropy)
{ {
register int temp, nbits; register int temp, nbits;
@@ -329,6 +320,9 @@ emit_eobrun (phuff_entropy_ptr entropy)
nbits = 0; nbits = 0;
while ((temp >>= 1)) while ((temp >>= 1))
nbits++; 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); emit_symbol(entropy, entropy->ac_tbl_no, nbits << 4);
if (nbits) if (nbits)
@@ -347,7 +341,7 @@ emit_eobrun (phuff_entropy_ptr entropy)
* Emit a restart marker & resynchronize predictions. * Emit a restart marker & resynchronize predictions.
*/ */
LOCAL void LOCAL(void)
emit_restart (phuff_entropy_ptr entropy, int restart_num) emit_restart (phuff_entropy_ptr entropy, int restart_num)
{ {
int ci; int ci;
@@ -377,7 +371,7 @@ emit_restart (phuff_entropy_ptr entropy, int restart_num)
* or first pass of successive approximation). * or first pass of successive approximation).
*/ */
METHODDEF boolean METHODDEF(boolean)
encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
{ {
phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
@@ -427,6 +421,11 @@ encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
nbits++; nbits++;
temp >>= 1; 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 */ /* Count/emit the Huffman-coded symbol for the number of bits */
emit_symbol(entropy, compptr->dc_tbl_no, nbits); emit_symbol(entropy, compptr->dc_tbl_no, nbits);
@@ -459,7 +458,7 @@ encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
* or first pass of successive approximation). * or first pass of successive approximation).
*/ */
METHODDEF boolean METHODDEF(boolean)
encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
{ {
phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
@@ -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 */ nbits = 1; /* there must be at least one 1 bit */
while ((temp >>= 1)) while ((temp >>= 1))
nbits++; 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 */ /* Count/emit Huffman symbol for run length / number of bits */
emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + nbits); emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + nbits);
@@ -563,7 +565,7 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
* is not very clear on the point. * is not very clear on the point.
*/ */
METHODDEF boolean METHODDEF(boolean)
encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data) encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
{ {
phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
@@ -610,7 +612,7 @@ encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
* MCU encoding for AC successive approximation refinement scan. * MCU encoding for AC successive approximation refinement scan.
*/ */
METHODDEF boolean METHODDEF(boolean)
encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data) encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
{ {
phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
@@ -738,7 +740,7 @@ encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
* Finish up at the end of a Huffman-compressed progressive scan. * Finish up at the end of a Huffman-compressed progressive scan.
*/ */
METHODDEF void METHODDEF(void)
finish_pass_phuff (j_compress_ptr cinfo) finish_pass_phuff (j_compress_ptr cinfo)
{ {
phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
@@ -759,7 +761,7 @@ finish_pass_phuff (j_compress_ptr cinfo)
* Finish up a statistics-gathering pass and create the new Huffman tables. * Finish up a statistics-gathering pass and create the new Huffman tables.
*/ */
METHODDEF void METHODDEF(void)
finish_pass_gather_phuff (j_compress_ptr cinfo) finish_pass_gather_phuff (j_compress_ptr cinfo)
{ {
phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
@@ -806,7 +808,7 @@ finish_pass_gather_phuff (j_compress_ptr cinfo)
* Module initialization routine for progressive Huffman entropy encoding. * Module initialization routine for progressive Huffman entropy encoding.
*/ */
GLOBAL void GLOBAL(void)
jinit_phuff_encoder (j_compress_ptr cinfo) jinit_phuff_encoder (j_compress_ptr cinfo)
{ {
phuff_entropy_ptr entropy; phuff_entropy_ptr entropy;

View File

@@ -1,7 +1,7 @@
/* /*
* jcprepct.c * jcprepct.c
* *
* Copyright (C) 1994, Thomas G. Lane. * Copyright (C) 1994-1996, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -74,7 +74,7 @@ typedef my_prep_controller * my_prep_ptr;
* Initialize for a processing pass. * Initialize for a processing pass.
*/ */
METHODDEF void METHODDEF(void)
start_pass_prep (j_compress_ptr cinfo, J_BUF_MODE pass_mode) start_pass_prep (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
{ {
my_prep_ptr prep = (my_prep_ptr) cinfo->prep; my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
@@ -102,7 +102,7 @@ start_pass_prep (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
* by duplicating the bottom row. * by duplicating the bottom row.
*/ */
LOCAL void LOCAL(void)
expand_bottom_edge (JSAMPARRAY image_data, JDIMENSION num_cols, expand_bottom_edge (JSAMPARRAY image_data, JDIMENSION num_cols,
int input_rows, int output_rows) int input_rows, int output_rows)
{ {
@@ -124,7 +124,7 @@ expand_bottom_edge (JSAMPARRAY image_data, JDIMENSION num_cols,
* input rows. * input rows.
*/ */
METHODDEF void METHODDEF(void)
pre_process_data (j_compress_ptr cinfo, pre_process_data (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
JDIMENSION in_rows_avail, JDIMENSION in_rows_avail,
@@ -191,7 +191,7 @@ pre_process_data (j_compress_ptr cinfo,
* Process some data in the context case. * Process some data in the context case.
*/ */
METHODDEF void METHODDEF(void)
pre_process_context (j_compress_ptr cinfo, pre_process_context (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
JDIMENSION in_rows_avail, JDIMENSION in_rows_avail,
@@ -202,7 +202,6 @@ pre_process_context (j_compress_ptr cinfo,
int numrows, ci; int numrows, ci;
int buf_height = cinfo->max_v_samp_factor * 3; int buf_height = cinfo->max_v_samp_factor * 3;
JDIMENSION inrows; JDIMENSION inrows;
jpeg_component_info * compptr;
while (*out_row_group_ctr < out_row_groups_avail) { while (*out_row_group_ctr < out_row_groups_avail) {
if (*in_row_ctr < in_rows_avail) { if (*in_row_ctr < in_rows_avail) {
@@ -232,15 +231,14 @@ pre_process_context (j_compress_ptr cinfo,
/* Return for more data, unless we are at the bottom of the image. */ /* Return for more data, unless we are at the bottom of the image. */
if (prep->rows_to_go != 0) if (prep->rows_to_go != 0)
break; break;
} /* When at bottom of image, pad to fill the conversion buffer. */
/* If at bottom of image, pad to fill the conversion buffer. */ if (prep->next_buf_row < prep->next_buf_stop) {
if (prep->rows_to_go == 0 && for (ci = 0; ci < cinfo->num_components; ci++) {
prep->next_buf_row < prep->next_buf_stop) { expand_bottom_edge(prep->color_buf[ci], cinfo->image_width,
for (ci = 0; ci < cinfo->num_components; ci++) { prep->next_buf_row, prep->next_buf_stop);
expand_bottom_edge(prep->color_buf[ci], cinfo->image_width, }
prep->next_buf_row, prep->next_buf_stop); prep->next_buf_row = prep->next_buf_stop;
} }
prep->next_buf_row = prep->next_buf_stop;
} }
/* If we've gotten enough data, downsample a row group. */ /* If we've gotten enough data, downsample a row group. */
if (prep->next_buf_row == prep->next_buf_stop) { if (prep->next_buf_row == prep->next_buf_stop) {
@@ -257,21 +255,6 @@ pre_process_context (j_compress_ptr cinfo,
prep->next_buf_row = 0; prep->next_buf_row = 0;
prep->next_buf_stop = prep->next_buf_row + cinfo->max_v_samp_factor; prep->next_buf_stop = prep->next_buf_row + cinfo->max_v_samp_factor;
} }
/* If at bottom of image, pad the output to a full iMCU height.
* Note we assume the caller is providing a one-iMCU-height output buffer!
*/
if (prep->rows_to_go == 0 &&
*out_row_group_ctr < out_row_groups_avail) {
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
expand_bottom_edge(output_buf[ci],
compptr->width_in_blocks * DCTSIZE,
(int) (*out_row_group_ctr * compptr->v_samp_factor),
(int) (out_row_groups_avail * compptr->v_samp_factor));
}
*out_row_group_ctr = out_row_groups_avail;
break; /* can exit outer loop without test */
}
} }
} }
@@ -280,7 +263,7 @@ pre_process_context (j_compress_ptr cinfo,
* Create the wrapped-around downsampling input buffer needed for context mode. * Create the wrapped-around downsampling input buffer needed for context mode.
*/ */
LOCAL void LOCAL(void)
create_context_buffer (j_compress_ptr cinfo) create_context_buffer (j_compress_ptr cinfo)
{ {
my_prep_ptr prep = (my_prep_ptr) cinfo->prep; my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
@@ -328,7 +311,7 @@ create_context_buffer (j_compress_ptr cinfo)
* Initialize preprocessing controller. * Initialize preprocessing controller.
*/ */
GLOBAL void GLOBAL(void)
jinit_c_prep_controller (j_compress_ptr cinfo, boolean need_full_buffer) jinit_c_prep_controller (j_compress_ptr cinfo, boolean need_full_buffer)
{ {
my_prep_ptr prep; my_prep_ptr prep;

View File

@@ -1,7 +1,8 @@
/* /*
* jcsample.c * jcsample.c
* *
* Copyright (C) 1991-1994, Thomas G. Lane. * 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. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -48,6 +49,7 @@
#define JPEG_INTERNALS #define JPEG_INTERNALS
#include "jinclude.h" #include "jinclude.h"
#include "jpeglib.h" #include "jpeglib.h"
#include "jsimd.h"
/* Pointer to routine to downsample a single component */ /* Pointer to routine to downsample a single component */
@@ -71,7 +73,7 @@ typedef my_downsampler * my_downsample_ptr;
* Initialize for a downsampling pass. * Initialize for a downsampling pass.
*/ */
METHODDEF void METHODDEF(void)
start_pass_downsample (j_compress_ptr cinfo) start_pass_downsample (j_compress_ptr cinfo)
{ {
/* no work for now */ /* no work for now */
@@ -83,7 +85,7 @@ start_pass_downsample (j_compress_ptr cinfo)
* by duplicating the rightmost samples. * by duplicating the rightmost samples.
*/ */
LOCAL void LOCAL(void)
expand_right_edge (JSAMPARRAY image_data, int num_rows, expand_right_edge (JSAMPARRAY image_data, int num_rows,
JDIMENSION input_cols, JDIMENSION output_cols) JDIMENSION input_cols, JDIMENSION output_cols)
{ {
@@ -110,7 +112,7 @@ expand_right_edge (JSAMPARRAY image_data, int num_rows,
* In this version we simply downsample each component independently. * In this version we simply downsample each component independently.
*/ */
METHODDEF void METHODDEF(void)
sep_downsample (j_compress_ptr cinfo, sep_downsample (j_compress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION in_row_index, JSAMPIMAGE input_buf, JDIMENSION in_row_index,
JSAMPIMAGE output_buf, JDIMENSION out_row_group_index) JSAMPIMAGE output_buf, JDIMENSION out_row_group_index)
@@ -136,7 +138,7 @@ sep_downsample (j_compress_ptr cinfo,
* Note that this version is not actually used for customary sampling ratios. * Note that this version is not actually used for customary sampling ratios.
*/ */
METHODDEF void METHODDEF(void)
int_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, int_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY output_data) JSAMPARRAY input_data, JSAMPARRAY output_data)
{ {
@@ -183,7 +185,7 @@ int_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
* without smoothing. * without smoothing.
*/ */
METHODDEF void METHODDEF(void)
fullsize_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, fullsize_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY output_data) JSAMPARRAY input_data, JSAMPARRAY output_data)
{ {
@@ -208,7 +210,7 @@ fullsize_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
* alternate pixel locations (a simple ordered dither pattern). * alternate pixel locations (a simple ordered dither pattern).
*/ */
METHODDEF void METHODDEF(void)
h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY output_data) JSAMPARRAY input_data, JSAMPARRAY output_data)
{ {
@@ -245,7 +247,7 @@ h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
* without smoothing. * without smoothing.
*/ */
METHODDEF void METHODDEF(void)
h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY output_data) JSAMPARRAY input_data, JSAMPARRAY output_data)
{ {
@@ -288,7 +290,7 @@ h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
* with smoothing. One row of context is required. * with smoothing. One row of context is required.
*/ */
METHODDEF void METHODDEF(void)
h2v2_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, h2v2_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY output_data) JSAMPARRAY input_data, JSAMPARRAY output_data)
{ {
@@ -388,7 +390,7 @@ h2v2_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
* with smoothing. One row of context is required. * with smoothing. One row of context is required.
*/ */
METHODDEF void METHODDEF(void)
fullsize_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info *compptr, fullsize_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info *compptr,
JSAMPARRAY input_data, JSAMPARRAY output_data) JSAMPARRAY input_data, JSAMPARRAY output_data)
{ {
@@ -460,7 +462,7 @@ fullsize_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info *compptr,
* Note that we must select a routine for each component. * Note that we must select a routine for each component.
*/ */
GLOBAL void GLOBAL(void)
jinit_downsampler (j_compress_ptr cinfo) jinit_downsampler (j_compress_ptr cinfo)
{ {
my_downsample_ptr downsample; my_downsample_ptr downsample;
@@ -494,7 +496,10 @@ jinit_downsampler (j_compress_ptr cinfo)
} else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor && } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
compptr->v_samp_factor == cinfo->max_v_samp_factor) { compptr->v_samp_factor == cinfo->max_v_samp_factor) {
smoothok = FALSE; 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 && } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
compptr->v_samp_factor * 2 == cinfo->max_v_samp_factor) { compptr->v_samp_factor * 2 == cinfo->max_v_samp_factor) {
#ifdef INPUT_SMOOTHING_SUPPORTED #ifdef INPUT_SMOOTHING_SUPPORTED
@@ -503,7 +508,10 @@ jinit_downsampler (j_compress_ptr cinfo)
downsample->pub.need_context_rows = TRUE; downsample->pub.need_context_rows = TRUE;
} else } else
#endif #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 && } else if ((cinfo->max_h_samp_factor % compptr->h_samp_factor) == 0 &&
(cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0) { (cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0) {
smoothok = FALSE; smoothok = FALSE;

View File

@@ -1,7 +1,7 @@
/* /*
* jctrans.c * jctrans.c
* *
* Copyright (C) 1995, Thomas G. Lane. * Copyright (C) 1995-1998, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -16,9 +16,9 @@
/* Forward declarations */ /* Forward declarations */
LOCAL void transencode_master_selection LOCAL(void) transencode_master_selection
JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)); JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays));
LOCAL void transencode_coef_controller LOCAL(void) transencode_coef_controller
JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)); JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays));
@@ -34,7 +34,7 @@ LOCAL void transencode_coef_controller
* typically will be realized during this routine and filled afterwards. * typically will be realized during this routine and filled afterwards.
*/ */
GLOBAL void GLOBAL(void)
jpeg_write_coefficients (j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays) jpeg_write_coefficients (j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)
{ {
if (cinfo->global_state != CSTATE_START) if (cinfo->global_state != CSTATE_START)
@@ -59,7 +59,7 @@ jpeg_write_coefficients (j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)
* scan script and Huffman optimization) are left in their default states. * scan script and Huffman optimization) are left in their default states.
*/ */
GLOBAL void GLOBAL(void)
jpeg_copy_critical_parameters (j_decompress_ptr srcinfo, jpeg_copy_critical_parameters (j_decompress_ptr srcinfo,
j_compress_ptr dstinfo) j_compress_ptr dstinfo)
{ {
@@ -129,6 +129,23 @@ jpeg_copy_critical_parameters (j_decompress_ptr srcinfo,
* instead we rely on jpeg_set_colorspace to have made a suitable choice. * 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;
}
} }
@@ -137,7 +154,7 @@ jpeg_copy_critical_parameters (j_decompress_ptr srcinfo,
* This substitutes for jcinit.c's initialization of the full compressor. * This substitutes for jcinit.c's initialization of the full compressor.
*/ */
LOCAL void LOCAL(void)
transencode_master_selection (j_compress_ptr cinfo, transencode_master_selection (j_compress_ptr cinfo,
jvirt_barray_ptr * coef_arrays) jvirt_barray_ptr * coef_arrays)
{ {
@@ -170,7 +187,7 @@ transencode_master_selection (j_compress_ptr cinfo,
/* We can now tell the memory manager to allocate virtual arrays. */ /* We can now tell the memory manager to allocate virtual arrays. */
(*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo); (*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. * Frame and scan headers are postponed till later.
* This lets application insert special markers after the SOI. * This lets application insert special markers after the SOI.
*/ */
@@ -206,7 +223,7 @@ typedef struct {
typedef my_coef_controller * my_coef_ptr; typedef my_coef_controller * my_coef_ptr;
LOCAL void LOCAL(void)
start_iMCU_row (j_compress_ptr cinfo) start_iMCU_row (j_compress_ptr cinfo)
/* Reset within-iMCU-row counters for a new row */ /* Reset within-iMCU-row counters for a new row */
{ {
@@ -234,7 +251,7 @@ start_iMCU_row (j_compress_ptr cinfo)
* Initialize for a processing pass. * Initialize for a processing pass.
*/ */
METHODDEF void METHODDEF(void)
start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode) start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
{ {
my_coef_ptr coef = (my_coef_ptr) cinfo->coef; my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
@@ -257,7 +274,7 @@ start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
* NB: input_buf is ignored; it is likely to be a NULL pointer. * NB: input_buf is ignored; it is likely to be a NULL pointer.
*/ */
METHODDEF boolean METHODDEF(boolean)
compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf) compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
{ {
my_coef_ptr coef = (my_coef_ptr) cinfo->coef; my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
@@ -342,7 +359,7 @@ compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
* with unitheight at least v_samp_factor. * with unitheight at least v_samp_factor.
*/ */
LOCAL void LOCAL(void)
transencode_coef_controller (j_compress_ptr cinfo, transencode_coef_controller (j_compress_ptr cinfo,
jvirt_barray_ptr * coef_arrays) jvirt_barray_ptr * coef_arrays)
{ {

View File

@@ -1,7 +1,7 @@
/* /*
* jdapimin.c * jdapimin.c
* *
* Copyright (C) 1994-1995, Thomas G. Lane. * Copyright (C) 1994-1998, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -26,18 +26,31 @@
* The error manager must already be set up (in case memory manager fails). * The error manager must already be set up (in case memory manager fails).
*/ */
GLOBAL void GLOBAL(void)
jpeg_create_decompress (j_decompress_ptr cinfo) jpeg_CreateDecompress (j_decompress_ptr cinfo, int version, size_t structsize)
{ {
int i; int i;
/* For debugging purposes, zero the whole master structure. /* Guard against version mismatches between library and caller. */
* But error manager pointer is already there, so save and restore it. cinfo->mem = NULL; /* so jpeg_destroy knows mem mgr not called */
if (version != JPEG_LIB_VERSION)
ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version);
if (structsize != SIZEOF(struct jpeg_decompress_struct))
ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE,
(int) SIZEOF(struct jpeg_decompress_struct), (int) structsize);
/* 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; struct jpeg_error_mgr * err = cinfo->err;
void * client_data = cinfo->client_data; /* ignore Purify complaint here */
MEMZERO(cinfo, SIZEOF(struct jpeg_decompress_struct)); MEMZERO(cinfo, SIZEOF(struct jpeg_decompress_struct));
cinfo->err = err; cinfo->err = err;
cinfo->client_data = client_data;
} }
cinfo->is_decompressor = TRUE; cinfo->is_decompressor = TRUE;
@@ -59,6 +72,7 @@ jpeg_create_decompress (j_decompress_ptr cinfo)
/* Initialize marker processor so application can override methods /* Initialize marker processor so application can override methods
* for COM, APPn markers before calling jpeg_read_header. * for COM, APPn markers before calling jpeg_read_header.
*/ */
cinfo->marker_list = NULL;
jinit_marker_reader(cinfo); jinit_marker_reader(cinfo);
/* And initialize the overall input controller. */ /* And initialize the overall input controller. */
@@ -73,7 +87,7 @@ jpeg_create_decompress (j_decompress_ptr cinfo)
* Destruction of a JPEG decompression object * Destruction of a JPEG decompression object
*/ */
GLOBAL void GLOBAL(void)
jpeg_destroy_decompress (j_decompress_ptr cinfo) jpeg_destroy_decompress (j_decompress_ptr cinfo)
{ {
jpeg_destroy((j_common_ptr) cinfo); /* use common routine */ jpeg_destroy((j_common_ptr) cinfo); /* use common routine */
@@ -85,35 +99,18 @@ jpeg_destroy_decompress (j_decompress_ptr cinfo)
* but don't destroy the object itself. * but don't destroy the object itself.
*/ */
GLOBAL void GLOBAL(void)
jpeg_abort_decompress (j_decompress_ptr cinfo) jpeg_abort_decompress (j_decompress_ptr cinfo)
{ {
jpeg_abort((j_common_ptr) cinfo); /* use common routine */ jpeg_abort((j_common_ptr) cinfo); /* use common routine */
} }
/*
* 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. * Set default decompression parameters.
*/ */
LOCAL void LOCAL(void)
default_decompress_parms (j_decompress_ptr cinfo) default_decompress_parms (j_decompress_ptr cinfo)
{ {
/* Guess the input colorspace, and set output colorspace accordingly. */ /* Guess the input colorspace, and set output colorspace accordingly. */
@@ -240,7 +237,7 @@ default_decompress_parms (j_decompress_ptr cinfo)
* extra error checking. * extra error checking.
*/ */
GLOBAL int GLOBAL(int)
jpeg_read_header (j_decompress_ptr cinfo, boolean require_image) jpeg_read_header (j_decompress_ptr cinfo, boolean require_image)
{ {
int retcode; int retcode;
@@ -286,7 +283,7 @@ jpeg_read_header (j_decompress_ptr cinfo, boolean require_image)
* method. * method.
*/ */
GLOBAL int GLOBAL(int)
jpeg_consume_input (j_decompress_ptr cinfo) jpeg_consume_input (j_decompress_ptr cinfo)
{ {
int retcode = JPEG_SUSPENDED; int retcode = JPEG_SUSPENDED;
@@ -333,7 +330,7 @@ jpeg_consume_input (j_decompress_ptr cinfo)
* Have we finished reading the input file? * Have we finished reading the input file?
*/ */
GLOBAL boolean GLOBAL(boolean)
jpeg_input_complete (j_decompress_ptr cinfo) jpeg_input_complete (j_decompress_ptr cinfo)
{ {
/* Check for valid jpeg object */ /* Check for valid jpeg object */
@@ -348,7 +345,7 @@ jpeg_input_complete (j_decompress_ptr cinfo)
* Is there more than one scan? * Is there more than one scan?
*/ */
GLOBAL boolean GLOBAL(boolean)
jpeg_has_multiple_scans (j_decompress_ptr cinfo) jpeg_has_multiple_scans (j_decompress_ptr cinfo)
{ {
/* Only valid after jpeg_read_header completes */ /* Only valid after jpeg_read_header completes */
@@ -368,7 +365,7 @@ jpeg_has_multiple_scans (j_decompress_ptr cinfo)
* a suspending data source is used. * a suspending data source is used.
*/ */
GLOBAL boolean GLOBAL(boolean)
jpeg_finish_decompress (j_decompress_ptr cinfo) jpeg_finish_decompress (j_decompress_ptr cinfo)
{ {
if ((cinfo->global_state == DSTATE_SCANNING || if ((cinfo->global_state == DSTATE_SCANNING ||

View File

@@ -1,7 +1,7 @@
/* /*
* jdapistd.c * jdapistd.c
* *
* Copyright (C) 1994-1995, Thomas G. Lane. * Copyright (C) 1994-1996, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -20,7 +20,7 @@
/* Forward declarations */ /* Forward declarations */
LOCAL boolean output_pass_setup JPP((j_decompress_ptr cinfo)); LOCAL(boolean) output_pass_setup JPP((j_decompress_ptr cinfo));
/* /*
@@ -34,7 +34,7 @@ LOCAL boolean output_pass_setup JPP((j_decompress_ptr cinfo));
* a suspending data source is used. * a suspending data source is used.
*/ */
GLOBAL boolean GLOBAL(boolean)
jpeg_start_decompress (j_decompress_ptr cinfo) jpeg_start_decompress (j_decompress_ptr cinfo)
{ {
if (cinfo->global_state == DSTATE_READY) { if (cinfo->global_state == DSTATE_READY) {
@@ -91,7 +91,7 @@ jpeg_start_decompress (j_decompress_ptr cinfo)
* If suspended, returns FALSE and sets global_state = DSTATE_PRESCAN. * If suspended, returns FALSE and sets global_state = DSTATE_PRESCAN.
*/ */
LOCAL boolean LOCAL(boolean)
output_pass_setup (j_decompress_ptr cinfo) output_pass_setup (j_decompress_ptr cinfo)
{ {
if (cinfo->global_state != DSTATE_PRESCAN) { if (cinfo->global_state != DSTATE_PRESCAN) {
@@ -148,7 +148,7 @@ output_pass_setup (j_decompress_ptr cinfo)
* an oversize buffer (max_lines > scanlines remaining) is not an error. * an oversize buffer (max_lines > scanlines remaining) is not an error.
*/ */
GLOBAL JDIMENSION GLOBAL(JDIMENSION)
jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines, jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines,
JDIMENSION max_lines) JDIMENSION max_lines)
{ {
@@ -181,7 +181,7 @@ jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines,
* Processes exactly one iMCU row per call, unless suspended. * Processes exactly one iMCU row per call, unless suspended.
*/ */
GLOBAL JDIMENSION GLOBAL(JDIMENSION)
jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data, jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data,
JDIMENSION max_lines) JDIMENSION max_lines)
{ {
@@ -224,7 +224,7 @@ jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data,
* Initialize for an output pass in buffered-image mode. * Initialize for an output pass in buffered-image mode.
*/ */
GLOBAL boolean GLOBAL(boolean)
jpeg_start_output (j_decompress_ptr cinfo, int scan_number) jpeg_start_output (j_decompress_ptr cinfo, int scan_number)
{ {
if (cinfo->global_state != DSTATE_BUFIMAGE && if (cinfo->global_state != DSTATE_BUFIMAGE &&
@@ -249,7 +249,7 @@ jpeg_start_output (j_decompress_ptr cinfo, int scan_number)
* a suspending data source is used. * a suspending data source is used.
*/ */
GLOBAL boolean GLOBAL(boolean)
jpeg_finish_output (j_decompress_ptr cinfo) jpeg_finish_output (j_decompress_ptr cinfo)
{ {
if ((cinfo->global_state == DSTATE_SCANNING || if ((cinfo->global_state == DSTATE_SCANNING ||

View File

@@ -1,7 +1,7 @@
/* /*
* jdatadst.c * jdatadst.c
* *
* Copyright (C) 1994, Thomas G. Lane. * Copyright (C) 1994-1996, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -39,7 +39,7 @@ typedef my_destination_mgr * my_dest_ptr;
* before any data is actually written. * before any data is actually written.
*/ */
METHODDEF void METHODDEF(void)
init_destination (j_compress_ptr cinfo) init_destination (j_compress_ptr cinfo)
{ {
my_dest_ptr dest = (my_dest_ptr) cinfo->dest; my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
@@ -77,7 +77,7 @@ init_destination (j_compress_ptr cinfo)
* write it out when emptying the buffer externally. * write it out when emptying the buffer externally.
*/ */
METHODDEF boolean METHODDEF(boolean)
empty_output_buffer (j_compress_ptr cinfo) empty_output_buffer (j_compress_ptr cinfo)
{ {
my_dest_ptr dest = (my_dest_ptr) cinfo->dest; my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
@@ -102,7 +102,7 @@ empty_output_buffer (j_compress_ptr cinfo)
* for error exit. * for error exit.
*/ */
METHODDEF void METHODDEF(void)
term_destination (j_compress_ptr cinfo) term_destination (j_compress_ptr cinfo)
{ {
my_dest_ptr dest = (my_dest_ptr) cinfo->dest; my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
@@ -126,7 +126,7 @@ term_destination (j_compress_ptr cinfo)
* for closing it after finishing compression. * for closing it after finishing compression.
*/ */
GLOBAL void GLOBAL(void)
jpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile) jpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile)
{ {
my_dest_ptr dest; my_dest_ptr dest;

View File

@@ -1,7 +1,7 @@
/* /*
* jdatasrc.c * jdatasrc.c
* *
* Copyright (C) 1994, Thomas G. Lane. * Copyright (C) 1994-1996, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -40,7 +40,7 @@ typedef my_source_mgr * my_src_ptr;
* before any data is actually read. * before any data is actually read.
*/ */
METHODDEF void METHODDEF(void)
init_source (j_decompress_ptr cinfo) init_source (j_decompress_ptr cinfo)
{ {
my_src_ptr src = (my_src_ptr) cinfo->src; my_src_ptr src = (my_src_ptr) cinfo->src;
@@ -86,7 +86,7 @@ init_source (j_decompress_ptr cinfo)
* the front of the buffer rather than discarding it. * the front of the buffer rather than discarding it.
*/ */
METHODDEF boolean METHODDEF(boolean)
fill_input_buffer (j_decompress_ptr cinfo) fill_input_buffer (j_decompress_ptr cinfo)
{ {
my_src_ptr src = (my_src_ptr) cinfo->src; my_src_ptr src = (my_src_ptr) cinfo->src;
@@ -124,7 +124,7 @@ fill_input_buffer (j_decompress_ptr cinfo)
* buffer is the application writer's problem. * buffer is the application writer's problem.
*/ */
METHODDEF void METHODDEF(void)
skip_input_data (j_decompress_ptr cinfo, long num_bytes) skip_input_data (j_decompress_ptr cinfo, long num_bytes)
{ {
my_src_ptr src = (my_src_ptr) cinfo->src; my_src_ptr src = (my_src_ptr) cinfo->src;
@@ -165,7 +165,7 @@ skip_input_data (j_decompress_ptr cinfo, long num_bytes)
* for error exit. * for error exit.
*/ */
METHODDEF void METHODDEF(void)
term_source (j_decompress_ptr cinfo) term_source (j_decompress_ptr cinfo)
{ {
/* no work necessary here */ /* no work necessary here */
@@ -178,7 +178,7 @@ term_source (j_decompress_ptr cinfo)
* for closing it after finishing decompression. * for closing it after finishing decompression.
*/ */
GLOBAL void GLOBAL(void)
jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile) jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile)
{ {
my_src_ptr src; my_src_ptr src;

View File

@@ -1,7 +1,7 @@
/* /*
* jdcoefct.c * jdcoefct.c
* *
* Copyright (C) 1994-1995, Thomas G. Lane. * Copyright (C) 1994-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -47,6 +47,9 @@ typedef struct {
*/ */
JBLOCKROW MCU_buffer[D_MAX_BLOCKS_IN_MCU]; JBLOCKROW MCU_buffer[D_MAX_BLOCKS_IN_MCU];
/* Temporary workspace for one MCU */
JCOEF * workspace;
#ifdef D_MULTISCAN_FILES_SUPPORTED #ifdef D_MULTISCAN_FILES_SUPPORTED
/* In multi-pass modes, we need a virtual block array for each component. */ /* In multi-pass modes, we need a virtual block array for each component. */
jvirt_barray_ptr whole_image[MAX_COMPONENTS]; jvirt_barray_ptr whole_image[MAX_COMPONENTS];
@@ -62,20 +65,20 @@ typedef struct {
typedef my_coef_controller * my_coef_ptr; typedef my_coef_controller * my_coef_ptr;
/* Forward declarations */ /* Forward declarations */
METHODDEF int decompress_onepass METHODDEF(int) decompress_onepass
JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf)); JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
#ifdef D_MULTISCAN_FILES_SUPPORTED #ifdef D_MULTISCAN_FILES_SUPPORTED
METHODDEF int decompress_data METHODDEF(int) decompress_data
JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf)); JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
#endif #endif
#ifdef BLOCK_SMOOTHING_SUPPORTED #ifdef BLOCK_SMOOTHING_SUPPORTED
LOCAL boolean smoothing_ok JPP((j_decompress_ptr cinfo)); LOCAL(boolean) smoothing_ok JPP((j_decompress_ptr cinfo));
METHODDEF int decompress_smooth_data METHODDEF(int) decompress_smooth_data
JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf)); JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
#endif #endif
LOCAL void LOCAL(void)
start_iMCU_row (j_decompress_ptr cinfo) start_iMCU_row (j_decompress_ptr cinfo)
/* Reset within-iMCU-row counters for a new row (input side) */ /* Reset within-iMCU-row counters for a new row (input side) */
{ {
@@ -103,7 +106,7 @@ start_iMCU_row (j_decompress_ptr cinfo)
* Initialize for an input processing pass. * Initialize for an input processing pass.
*/ */
METHODDEF void METHODDEF(void)
start_input_pass (j_decompress_ptr cinfo) start_input_pass (j_decompress_ptr cinfo)
{ {
cinfo->input_iMCU_row = 0; cinfo->input_iMCU_row = 0;
@@ -115,7 +118,7 @@ start_input_pass (j_decompress_ptr cinfo)
* Initialize for an output processing pass. * Initialize for an output processing pass.
*/ */
METHODDEF void METHODDEF(void)
start_output_pass (j_decompress_ptr cinfo) start_output_pass (j_decompress_ptr cinfo)
{ {
#ifdef BLOCK_SMOOTHING_SUPPORTED #ifdef BLOCK_SMOOTHING_SUPPORTED
@@ -139,11 +142,11 @@ start_output_pass (j_decompress_ptr cinfo)
* Input and output must run in lockstep since we have only a one-MCU buffer. * 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. * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
* *
* NB: output_buf contains a plane for each component in image. * NB: output_buf contains a plane for each component in image,
* For single pass, this is the same as the components in the scan. * which we index according to the component's SOF position.
*/ */
METHODDEF int METHODDEF(int)
decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
{ {
my_coef_ptr coef = (my_coef_ptr) cinfo->coef; my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
@@ -186,7 +189,8 @@ decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
inverse_DCT = cinfo->idct->inverse_DCT[compptr->component_index]; inverse_DCT = cinfo->idct->inverse_DCT[compptr->component_index];
useful_width = (MCU_col_num < last_MCU_col) ? compptr->MCU_width useful_width = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
: compptr->last_col_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; start_col = MCU_col_num * compptr->MCU_sample_width;
for (yindex = 0; yindex < compptr->MCU_height; yindex++) { for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
if (cinfo->input_iMCU_row < last_iMCU_row || if (cinfo->input_iMCU_row < last_iMCU_row ||
@@ -223,7 +227,7 @@ decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
* Dummy consume-input routine for single-pass operation. * Dummy consume-input routine for single-pass operation.
*/ */
METHODDEF int METHODDEF(int)
dummy_consume_data (j_decompress_ptr cinfo) dummy_consume_data (j_decompress_ptr cinfo)
{ {
return JPEG_SUSPENDED; /* Always indicate nothing was done */ return JPEG_SUSPENDED; /* Always indicate nothing was done */
@@ -239,7 +243,7 @@ dummy_consume_data (j_decompress_ptr cinfo)
* Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED. * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
*/ */
METHODDEF int METHODDEF(int)
consume_data (j_decompress_ptr cinfo) consume_data (j_decompress_ptr cinfo)
{ {
my_coef_ptr coef = (my_coef_ptr) cinfo->coef; my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
@@ -310,7 +314,7 @@ consume_data (j_decompress_ptr cinfo)
* NB: output_buf contains a plane for each component in image. * NB: output_buf contains a plane for each component in image.
*/ */
METHODDEF int METHODDEF(int)
decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
{ {
my_coef_ptr coef = (my_coef_ptr) cinfo->coef; my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
@@ -385,6 +389,13 @@ decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
* the coefficients it can estimate are not yet known to full precision. * the coefficients it can estimate are not yet known to full precision.
*/ */
/* Natural-order array positions of the first 5 zigzag-order coefficients */
#define Q01_POS 1
#define Q10_POS 8
#define Q20_POS 16
#define Q11_POS 9
#define Q02_POS 2
/* /*
* Determine whether block smoothing is applicable and safe. * Determine whether block smoothing is applicable and safe.
* We also latch the current states of the coef_bits[] entries for the * We also latch the current states of the coef_bits[] entries for the
@@ -393,7 +404,7 @@ decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
* more accurately than they really are. * more accurately than they really are.
*/ */
LOCAL boolean LOCAL(boolean)
smoothing_ok (j_decompress_ptr cinfo) smoothing_ok (j_decompress_ptr cinfo)
{ {
my_coef_ptr coef = (my_coef_ptr) cinfo->coef; my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
@@ -421,10 +432,13 @@ smoothing_ok (j_decompress_ptr cinfo)
if ((qtable = compptr->quant_table) == NULL) if ((qtable = compptr->quant_table) == NULL)
return FALSE; return FALSE;
/* Verify DC & first 5 AC quantizers are nonzero to avoid zero-divide. */ /* Verify DC & first 5 AC quantizers are nonzero to avoid zero-divide. */
for (coefi = 0; coefi <= 5; coefi++) { if (qtable->quantval[0] == 0 ||
if (qtable->quantval[coefi] == 0) qtable->quantval[Q01_POS] == 0 ||
return FALSE; qtable->quantval[Q10_POS] == 0 ||
} qtable->quantval[Q20_POS] == 0 ||
qtable->quantval[Q11_POS] == 0 ||
qtable->quantval[Q02_POS] == 0)
return FALSE;
/* DC values must be at least partly known for all components. */ /* DC values must be at least partly known for all components. */
coef_bits = cinfo->coef_bits[ci]; coef_bits = cinfo->coef_bits[ci];
if (coef_bits[0] < 0) if (coef_bits[0] < 0)
@@ -446,7 +460,7 @@ smoothing_ok (j_decompress_ptr cinfo)
* Variant of decompress_data for use when doing block smoothing. * Variant of decompress_data for use when doing block smoothing.
*/ */
METHODDEF int METHODDEF(int)
decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
{ {
my_coef_ptr coef = (my_coef_ptr) cinfo->coef; my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
@@ -460,13 +474,16 @@ decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
jpeg_component_info *compptr; jpeg_component_info *compptr;
inverse_DCT_method_ptr inverse_DCT; inverse_DCT_method_ptr inverse_DCT;
boolean first_row, last_row; boolean first_row, last_row;
JBLOCK workspace; JCOEF * workspace;
int *coef_bits; int *coef_bits;
JQUANT_TBL *quanttbl; JQUANT_TBL *quanttbl;
INT32 Q00,Q01,Q02,Q10,Q11,Q20, num; INT32 Q00,Q01,Q02,Q10,Q11,Q20, num;
int DC1,DC2,DC3,DC4,DC5,DC6,DC7,DC8,DC9; int DC1,DC2,DC3,DC4,DC5,DC6,DC7,DC8,DC9;
int Al, pred; 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. */ /* Force some input to be done if we are getting ahead of the input. */
while (cinfo->input_scan_number <= cinfo->output_scan_number && while (cinfo->input_scan_number <= cinfo->output_scan_number &&
! cinfo->inputctl->eoi_reached) { ! cinfo->inputctl->eoi_reached) {
@@ -521,11 +538,11 @@ decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
coef_bits = coef->coef_bits_latch + (ci * SAVED_COEFS); coef_bits = coef->coef_bits_latch + (ci * SAVED_COEFS);
quanttbl = compptr->quant_table; quanttbl = compptr->quant_table;
Q00 = quanttbl->quantval[0]; Q00 = quanttbl->quantval[0];
Q01 = quanttbl->quantval[1]; Q01 = quanttbl->quantval[Q01_POS];
Q10 = quanttbl->quantval[2]; Q10 = quanttbl->quantval[Q10_POS];
Q20 = quanttbl->quantval[3]; Q20 = quanttbl->quantval[Q20_POS];
Q11 = quanttbl->quantval[4]; Q11 = quanttbl->quantval[Q11_POS];
Q02 = quanttbl->quantval[5]; Q02 = quanttbl->quantval[Q02_POS];
inverse_DCT = cinfo->idct->inverse_DCT[ci]; inverse_DCT = cinfo->idct->inverse_DCT[ci];
output_ptr = output_buf[ci]; output_ptr = output_buf[ci];
/* Loop over all DCT blocks to be processed. */ /* Loop over all DCT blocks to be processed. */
@@ -661,7 +678,7 @@ decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
* Initialize coefficient buffer controller. * Initialize coefficient buffer controller.
*/ */
GLOBAL void GLOBAL(void)
jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer) jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
{ {
my_coef_ptr coef; my_coef_ptr coef;
@@ -722,4 +739,9 @@ jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
coef->pub.decompress_data = decompress_onepass; coef->pub.decompress_data = decompress_onepass;
coef->pub.coef_arrays = NULL; /* flag for no virtual arrays */ 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 * jdcolor.c
* *
* Copyright (C) 1991-1995, 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. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -11,6 +13,7 @@
#define JPEG_INTERNALS #define JPEG_INTERNALS
#include "jinclude.h" #include "jinclude.h"
#include "jpeglib.h" #include "jpeglib.h"
#include "jsimd.h"
/* Private subobject */ /* Private subobject */
@@ -66,7 +69,7 @@ typedef my_color_deconverter * my_cconvert_ptr;
* Initialize tables for YCC->RGB colorspace conversion. * Initialize tables for YCC->RGB colorspace conversion.
*/ */
LOCAL void LOCAL(void)
build_ycc_rgb_table (j_decompress_ptr cinfo) build_ycc_rgb_table (j_decompress_ptr cinfo)
{ {
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
@@ -116,7 +119,7 @@ build_ycc_rgb_table (j_decompress_ptr cinfo)
* offset required on that side. * offset required on that side.
*/ */
METHODDEF void METHODDEF(void)
ycc_rgb_convert (j_decompress_ptr cinfo, ycc_rgb_convert (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION input_row, JSAMPIMAGE input_buf, JDIMENSION input_row,
JSAMPARRAY output_buf, int num_rows) JSAMPARRAY output_buf, int num_rows)
@@ -146,12 +149,12 @@ ycc_rgb_convert (j_decompress_ptr cinfo,
cb = GETJSAMPLE(inptr1[col]); cb = GETJSAMPLE(inptr1[col]);
cr = GETJSAMPLE(inptr2[col]); cr = GETJSAMPLE(inptr2[col]);
/* Range-limiting is essential due to noise introduced by DCT losses. */ /* Range-limiting is essential due to noise introduced by DCT losses. */
outptr[RGB_RED] = range_limit[y + Crrtab[cr]]; outptr[rgb_red[cinfo->out_color_space]] = range_limit[y + Crrtab[cr]];
outptr[RGB_GREEN] = range_limit[y + outptr[rgb_green[cinfo->out_color_space]] = range_limit[y +
((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
SCALEBITS))]; SCALEBITS))];
outptr[RGB_BLUE] = range_limit[y + Cbbtab[cb]]; outptr[rgb_blue[cinfo->out_color_space]] = range_limit[y + Cbbtab[cb]];
outptr += RGB_PIXELSIZE; outptr += rgb_pixelsize[cinfo->out_color_space];
} }
} }
} }
@@ -165,7 +168,7 @@ ycc_rgb_convert (j_decompress_ptr cinfo,
* converting from separate-planes to interleaved representation. * converting from separate-planes to interleaved representation.
*/ */
METHODDEF void METHODDEF(void)
null_convert (j_decompress_ptr cinfo, null_convert (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION input_row, JSAMPIMAGE input_buf, JDIMENSION input_row,
JSAMPARRAY output_buf, int num_rows) JSAMPARRAY output_buf, int num_rows)
@@ -197,7 +200,7 @@ null_convert (j_decompress_ptr cinfo,
* we just copy the Y (luminance) component and ignore chrominance. * we just copy the Y (luminance) component and ignore chrominance.
*/ */
METHODDEF void METHODDEF(void)
grayscale_convert (j_decompress_ptr cinfo, grayscale_convert (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION input_row, JSAMPIMAGE input_buf, JDIMENSION input_row,
JSAMPARRAY output_buf, int num_rows) JSAMPARRAY output_buf, int num_rows)
@@ -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. * Adobe-style YCCK->CMYK conversion.
* We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
@@ -214,7 +249,7 @@ grayscale_convert (j_decompress_ptr cinfo,
* We assume build_ycc_rgb_table has been called. * We assume build_ycc_rgb_table has been called.
*/ */
METHODDEF void METHODDEF(void)
ycck_cmyk_convert (j_decompress_ptr cinfo, ycck_cmyk_convert (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION input_row, JSAMPIMAGE input_buf, JDIMENSION input_row,
JSAMPARRAY output_buf, int num_rows) JSAMPARRAY output_buf, int num_rows)
@@ -262,7 +297,7 @@ ycck_cmyk_convert (j_decompress_ptr cinfo,
* Empty method for start_pass. * Empty method for start_pass.
*/ */
METHODDEF void METHODDEF(void)
start_pass_dcolor (j_decompress_ptr cinfo) start_pass_dcolor (j_decompress_ptr cinfo)
{ {
/* no work needed */ /* no work needed */
@@ -273,7 +308,7 @@ start_pass_dcolor (j_decompress_ptr cinfo)
* Module initialization routine for output colorspace conversion. * Module initialization routine for output colorspace conversion.
*/ */
GLOBAL void GLOBAL(void)
jinit_color_deconverter (j_decompress_ptr cinfo) jinit_color_deconverter (j_decompress_ptr cinfo)
{ {
my_cconvert_ptr cconvert; my_cconvert_ptr cconvert;
@@ -329,11 +364,24 @@ jinit_color_deconverter (j_decompress_ptr cinfo)
break; break;
case JCS_RGB: 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) { if (cinfo->jpeg_color_space == JCS_YCbCr) {
cconvert->pub.color_convert = ycc_rgb_convert; if (jsimd_can_ycc_rgb())
build_ycc_rgb_table(cinfo); cconvert->pub.color_convert = jsimd_ycc_rgb_convert;
} else if (cinfo->jpeg_color_space == JCS_RGB && RGB_PIXELSIZE == 3) { 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; cconvert->pub.color_convert = null_convert;
} else } else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);

36
jdct.h
View File

@@ -1,7 +1,7 @@
/* /*
* jdct.h * jdct.h
* *
* Copyright (C) 1994, Thomas G. Lane. * Copyright (C) 1994-1996, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -23,18 +23,26 @@
* have a range of +-8K for 8-bit data, +-128K for 12-bit data. This * have a range of +-8K for 8-bit data, +-128K for 12-bit data. This
* convention improves accuracy in integer implementations and saves some * convention improves accuracy in integer implementations and saves some
* work in floating-point ones. * 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 #if BITS_IN_JSAMPLE == 8
#ifndef WITH_SIMD
typedef int DCTELEM; /* 16 or 32 bits is fine */ 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 #else
typedef INT32 DCTELEM; /* must have 32 bits */ typedef INT32 DCTELEM; /* must have 32 bits */
typedef UINT32 UDCTELEM;
typedef unsigned long long UDCTELEM2;
#endif #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 * An inverse DCT routine is given a pointer to the input JBLOCK and a pointer
@@ -94,26 +102,26 @@ typedef FAST_FLOAT FLOAT_MULT_TYPE; /* preferred floating type */
/* Extern declarations for the forward and inverse DCT routines. */ /* Extern declarations for the forward and inverse DCT routines. */
EXTERN void jpeg_fdct_islow JPP((DCTELEM * data)); EXTERN(void) jpeg_fdct_islow JPP((DCTELEM * data));
EXTERN void jpeg_fdct_ifast JPP((DCTELEM * data)); EXTERN(void) jpeg_fdct_ifast JPP((DCTELEM * data));
EXTERN void jpeg_fdct_float JPP((FAST_FLOAT * data)); EXTERN(void) jpeg_fdct_float JPP((FAST_FLOAT * data));
EXTERN void jpeg_idct_islow EXTERN(void) jpeg_idct_islow
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN void jpeg_idct_ifast EXTERN(void) jpeg_idct_ifast
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN void jpeg_idct_float EXTERN(void) jpeg_idct_float
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN void jpeg_idct_4x4 EXTERN(void) jpeg_idct_4x4
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN void jpeg_idct_2x2 EXTERN(void) jpeg_idct_2x2
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN void jpeg_idct_1x1 EXTERN(void) jpeg_idct_1x1
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));

View File

@@ -1,7 +1,8 @@
/* /*
* jddctmgr.c * jddctmgr.c
* *
* Copyright (C) 1994-1995, Thomas G. Lane. * Copyright (C) 1994-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. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -19,6 +20,7 @@
#include "jinclude.h" #include "jinclude.h"
#include "jpeglib.h" #include "jpeglib.h"
#include "jdct.h" /* Private declarations for DCT subsystem */ #include "jdct.h" /* Private declarations for DCT subsystem */
#include "jsimddct.h"
/* /*
@@ -85,7 +87,7 @@ typedef union {
* a matching multiplier table. * a matching multiplier table.
*/ */
METHODDEF void METHODDEF(void)
start_pass (j_decompress_ptr cinfo) start_pass (j_decompress_ptr cinfo)
{ {
my_idct_ptr idct = (my_idct_ptr) cinfo->idct; my_idct_ptr idct = (my_idct_ptr) cinfo->idct;
@@ -105,11 +107,17 @@ start_pass (j_decompress_ptr cinfo)
method = JDCT_ISLOW; /* jidctred uses islow-style table */ method = JDCT_ISLOW; /* jidctred uses islow-style table */
break; break;
case 2: 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 */ method = JDCT_ISLOW; /* jidctred uses islow-style table */
break; break;
case 4: 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 */ method = JDCT_ISLOW; /* jidctred uses islow-style table */
break; break;
#endif #endif
@@ -117,19 +125,28 @@ start_pass (j_decompress_ptr cinfo)
switch (cinfo->dct_method) { switch (cinfo->dct_method) {
#ifdef DCT_ISLOW_SUPPORTED #ifdef DCT_ISLOW_SUPPORTED
case JDCT_ISLOW: 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; method = JDCT_ISLOW;
break; break;
#endif #endif
#ifdef DCT_IFAST_SUPPORTED #ifdef DCT_IFAST_SUPPORTED
case JDCT_IFAST: 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; method = JDCT_IFAST;
break; break;
#endif #endif
#ifdef DCT_FLOAT_SUPPORTED #ifdef DCT_FLOAT_SUPPORTED
case JDCT_FLOAT: 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; method = JDCT_FLOAT;
break; break;
#endif #endif
@@ -161,11 +178,11 @@ start_pass (j_decompress_ptr cinfo)
case JDCT_ISLOW: case JDCT_ISLOW:
{ {
/* For LL&M IDCT method, multipliers are equal to raw quantization /* For LL&M IDCT method, multipliers are equal to raw quantization
* coefficients, but are stored in natural order as ints. * coefficients, but are stored as ints to ensure access efficiency.
*/ */
ISLOW_MULT_TYPE * ismtbl = (ISLOW_MULT_TYPE *) compptr->dct_table; ISLOW_MULT_TYPE * ismtbl = (ISLOW_MULT_TYPE *) compptr->dct_table;
for (i = 0; i < DCTSIZE2; i++) { for (i = 0; i < DCTSIZE2; i++) {
ismtbl[i] = (ISLOW_MULT_TYPE) qtbl->quantval[jpeg_zigzag_order[i]]; ismtbl[i] = (ISLOW_MULT_TYPE) qtbl->quantval[i];
} }
} }
break; break;
@@ -178,7 +195,7 @@ start_pass (j_decompress_ptr cinfo)
* scalefactor[0] = 1 * scalefactor[0] = 1
* scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
* For integer operation, the multiplier table is to be scaled by * For integer operation, the multiplier table is to be scaled by
* IFAST_SCALE_BITS. The multipliers are stored in natural order. * IFAST_SCALE_BITS.
*/ */
IFAST_MULT_TYPE * ifmtbl = (IFAST_MULT_TYPE *) compptr->dct_table; IFAST_MULT_TYPE * ifmtbl = (IFAST_MULT_TYPE *) compptr->dct_table;
#define CONST_BITS 14 #define CONST_BITS 14
@@ -197,7 +214,7 @@ start_pass (j_decompress_ptr cinfo)
for (i = 0; i < DCTSIZE2; i++) { for (i = 0; i < DCTSIZE2; i++) {
ifmtbl[i] = (IFAST_MULT_TYPE) ifmtbl[i] = (IFAST_MULT_TYPE)
DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[jpeg_zigzag_order[i]], DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
(INT32) aanscales[i]), (INT32) aanscales[i]),
CONST_BITS-IFAST_SCALE_BITS); CONST_BITS-IFAST_SCALE_BITS);
} }
@@ -211,7 +228,6 @@ start_pass (j_decompress_ptr cinfo)
* coefficients scaled by scalefactor[row]*scalefactor[col], where * coefficients scaled by scalefactor[row]*scalefactor[col], where
* scalefactor[0] = 1 * scalefactor[0] = 1
* scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
* The multipliers are stored in natural order.
*/ */
FLOAT_MULT_TYPE * fmtbl = (FLOAT_MULT_TYPE *) compptr->dct_table; FLOAT_MULT_TYPE * fmtbl = (FLOAT_MULT_TYPE *) compptr->dct_table;
int row, col; int row, col;
@@ -224,7 +240,7 @@ start_pass (j_decompress_ptr cinfo)
for (row = 0; row < DCTSIZE; row++) { for (row = 0; row < DCTSIZE; row++) {
for (col = 0; col < DCTSIZE; col++) { for (col = 0; col < DCTSIZE; col++) {
fmtbl[i] = (FLOAT_MULT_TYPE) fmtbl[i] = (FLOAT_MULT_TYPE)
((double) qtbl->quantval[jpeg_zigzag_order[i]] * ((double) qtbl->quantval[i] *
aanscalefactor[row] * aanscalefactor[col]); aanscalefactor[row] * aanscalefactor[col]);
i++; i++;
} }
@@ -244,7 +260,7 @@ start_pass (j_decompress_ptr cinfo)
* Initialize IDCT manager. * Initialize IDCT manager.
*/ */
GLOBAL void GLOBAL(void)
jinit_inverse_dct (j_decompress_ptr cinfo) jinit_inverse_dct (j_decompress_ptr cinfo)
{ {
my_idct_ptr idct; my_idct_ptr idct;

608
jdhuff.c
View File

@@ -1,7 +1,7 @@
/* /*
* jdhuff.c * jdhuff.c
* *
* Copyright (C) 1991-1995, Thomas G. Lane. * Copyright (C) 1991-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -14,6 +14,21 @@
* storage only upon successful completion of an MCU. * storage 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 #define JPEG_INTERNALS
#include "jinclude.h" #include "jinclude.h"
#include "jpeglib.h" #include "jpeglib.h"
@@ -64,6 +79,15 @@ typedef struct {
/* Pointers to derived tables (these workspaces have image lifespan) */ /* Pointers to derived tables (these workspaces have image lifespan) */
d_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS]; d_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS];
d_derived_tbl * ac_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; } huff_entropy_decoder;
typedef huff_entropy_decoder * huff_entropy_ptr; typedef huff_entropy_decoder * huff_entropy_ptr;
@@ -73,11 +97,11 @@ typedef huff_entropy_decoder * huff_entropy_ptr;
* Initialize for a Huffman-compressed scan. * Initialize for a Huffman-compressed scan.
*/ */
METHODDEF void METHODDEF(void)
start_pass_huff_decoder (j_decompress_ptr cinfo) start_pass_huff_decoder (j_decompress_ptr cinfo)
{ {
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
int ci, dctbl, actbl; int ci, blkn, dctbl, actbl;
jpeg_component_info * compptr; jpeg_component_info * compptr;
/* Check that the scan parameters Ss, Se, Ah/Al are OK for sequential JPEG. /* Check that the scan parameters Ss, Se, Ah/Al are OK for sequential JPEG.
@@ -92,27 +116,37 @@ start_pass_huff_decoder (j_decompress_ptr cinfo)
compptr = cinfo->cur_comp_info[ci]; compptr = cinfo->cur_comp_info[ci];
dctbl = compptr->dc_tbl_no; dctbl = compptr->dc_tbl_no;
actbl = compptr->ac_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 */ /* Compute derived values for Huffman tables */
/* We may do this more than once for a table, but it's not expensive */ /* 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]); & 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]); & entropy->ac_derived_tbls[actbl]);
/* Initialize DC predictions to 0 */ /* Initialize DC predictions to 0 */
entropy->saved.last_dc_val[ci] = 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 */ /* Initialize bitread state variables */
entropy->bitstate.bits_left = 0; entropy->bitstate.bits_left = 0;
entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */ entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */
entropy->bitstate.printed_eod = FALSE; entropy->pub.insufficient_data = FALSE;
/* Initialize restart counter */ /* Initialize restart counter */
entropy->restarts_to_go = cinfo->restart_interval; entropy->restarts_to_go = cinfo->restart_interval;
@@ -121,20 +155,35 @@ start_pass_huff_decoder (j_decompress_ptr cinfo)
/* /*
* Compute the derived values for a Huffman table. * 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. * Note this is also used by jdphuff.c.
*/ */
GLOBAL void 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) d_derived_tbl ** pdtbl)
{ {
JHUFF_TBL *htbl;
d_derived_tbl *dtbl; d_derived_tbl *dtbl;
int p, i, l, si; int p, i, l, si, numsymbols;
int lookbits, ctr; int lookbits, ctr;
char huffsize[257]; char huffsize[257];
unsigned int huffcode[257]; unsigned int huffcode[257];
unsigned int code; 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. */ /* Allocate a workspace if we haven't already done so. */
if (*pdtbl == NULL) if (*pdtbl == NULL)
*pdtbl = (d_derived_tbl *) *pdtbl = (d_derived_tbl *)
@@ -144,17 +193,20 @@ jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, JHUFF_TBL * htbl,
dtbl->pub = htbl; /* fill in back link */ dtbl->pub = htbl; /* fill in back link */
/* Figure C.1: make table of Huffman code length for each symbol */ /* Figure C.1: make table of Huffman code length for each symbol */
/* Note that this is in code-length order. */
p = 0; p = 0;
for (l = 1; l <= 16; l++) { 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++] = (char) l;
} }
huffsize[p] = 0; huffsize[p] = 0;
numsymbols = p;
/* Figure C.2: generate the codes themselves */ /* 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; code = 0;
si = huffsize[0]; si = huffsize[0];
@@ -164,6 +216,11 @@ jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, JHUFF_TBL * htbl,
huffcode[p++] = code; huffcode[p++] = code;
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; code <<= 1;
si++; si++;
} }
@@ -173,8 +230,10 @@ jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, JHUFF_TBL * htbl,
p = 0; p = 0;
for (l = 1; l <= 16; l++) { for (l = 1; l <= 16; l++) {
if (htbl->bits[l]) { if (htbl->bits[l]) {
dtbl->valptr[l] = p; /* huffval[] index of 1st symbol of code length l */ /* valoffset[l] = huffval[] index of 1st symbol of code length l,
dtbl->mincode[l] = huffcode[p]; /* minimum code of length l */ * minus the minimum code of length l
*/
dtbl->valoffset[l] = (INT32) p - (INT32) huffcode[p];
p += htbl->bits[l]; p += htbl->bits[l];
dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */ dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */
} else { } else {
@@ -190,7 +249,8 @@ jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, JHUFF_TBL * htbl,
* with that code. * 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; p = 0;
for (l = 1; l <= HUFF_LOOKAHEAD; l++) { for (l = 1; l <= HUFF_LOOKAHEAD; l++) {
@@ -199,12 +259,25 @@ jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, JHUFF_TBL * htbl,
/* Generate left-justified code followed by all possible bit sequences */ /* Generate left-justified code followed by all possible bit sequences */
lookbits = huffcode[p] << (HUFF_LOOKAHEAD-l); lookbits = huffcode[p] << (HUFF_LOOKAHEAD-l);
for (ctr = 1 << (HUFF_LOOKAHEAD-l); ctr > 0; ctr--) { for (ctr = 1 << (HUFF_LOOKAHEAD-l); ctr > 0; ctr--) {
dtbl->look_nbits[lookbits] = l; dtbl->lookup[lookbits] = (l << HUFF_LOOKAHEAD) | htbl->huffval[p];
dtbl->look_sym[lookbits] = htbl->huffval[p];
lookbits++; 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);
}
}
} }
@@ -230,7 +303,7 @@ jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, JHUFF_TBL * htbl,
#endif #endif
GLOBAL boolean GLOBAL(boolean)
jpeg_fill_bit_buffer (bitread_working_state * state, jpeg_fill_bit_buffer (bitread_working_state * state,
register bit_buf_type get_buffer, register int bits_left, register bit_buf_type get_buffer, register int bits_left,
int nbits) int nbits)
@@ -239,68 +312,86 @@ jpeg_fill_bit_buffer (bitread_working_state * state,
/* Copy heavily used state fields into locals (hopefully registers) */ /* Copy heavily used state fields into locals (hopefully registers) */
register const JOCTET * next_input_byte = state->next_input_byte; register const JOCTET * next_input_byte = state->next_input_byte;
register size_t bytes_in_buffer = state->bytes_in_buffer; 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. */ /* 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.) */ /* (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) { if (cinfo->unread_marker == 0) { /* cannot advance past a marker */
/* Attempt to read a byte */ while (bits_left < MIN_GET_BITS) {
if (state->unread_marker != 0) register int c;
goto no_more_data; /* can't advance past a marker */
if (bytes_in_buffer == 0) { /* Attempt to read a byte */
if (! (*state->cinfo->src->fill_input_buffer) (state->cinfo)) if (bytes_in_buffer == 0) {
return FALSE; if (! (*cinfo->src->fill_input_buffer) (cinfo))
next_input_byte = state->cinfo->src->next_input_byte; return FALSE;
bytes_in_buffer = state->cinfo->src->bytes_in_buffer; next_input_byte = cinfo->src->next_input_byte;
} bytes_in_buffer = 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 */
} }
} bytes_in_buffer--;
c = GETJOCTET(*next_input_byte++);
/* OK, load c into get_buffer */ /* If it's 0xFF, check and discard stuffed zero byte */
get_buffer = (get_buffer << 8) | c; if (c == 0xFF) {
bits_left += 8; /* 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 */ /* Unload the local registers */
@@ -318,7 +409,7 @@ jpeg_fill_bit_buffer (bitread_working_state * state,
* See jdhuff.h for info about usage. * See jdhuff.h for info about usage.
*/ */
GLOBAL int GLOBAL(int)
jpeg_huff_decode (bitread_working_state * state, jpeg_huff_decode (bitread_working_state * state,
register bit_buf_type get_buffer, register int bits_left, register bit_buf_type get_buffer, register int bits_left,
d_derived_tbl * htbl, int min_bits) d_derived_tbl * htbl, int min_bits)
@@ -353,8 +444,7 @@ jpeg_huff_decode (bitread_working_state * state,
return 0; /* fake a zero as the safest result */ return 0; /* fake a zero as the safest result */
} }
return htbl->pub->huffval[ htbl->valptr[l] + return htbl->pub->huffval[ (int) (code + htbl->valoffset[l]) ];
((int) (code - htbl->mincode[l])) ];
} }
@@ -363,9 +453,10 @@ jpeg_huff_decode (bitread_working_state * state,
* On some machines, a shift and add will be faster than a table lookup. * On some machines, a shift and add will be faster than a table lookup.
*/ */
#define AVOID_TABLES
#ifdef 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 #else
@@ -389,7 +480,7 @@ static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */
* Returns FALSE if must suspend. * Returns FALSE if must suspend.
*/ */
LOCAL boolean LOCAL(boolean)
process_restart (j_decompress_ptr cinfo) process_restart (j_decompress_ptr cinfo)
{ {
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
@@ -411,13 +502,248 @@ process_restart (j_decompress_ptr cinfo)
/* Reset restart counter */ /* Reset restart counter */
entropy->restarts_to_go = cinfo->restart_interval; entropy->restarts_to_go = cinfo->restart_interval;
/* Next segment can get another out-of-data warning */ /* Reset out-of-data flag, unless read_restart_marker left us smack up
entropy->bitstate.printed_eod = FALSE; * 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; 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
#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]) ]; \
} \
}
/***************************************************************/
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. * Decode and return one MCU's worth of Huffman-compressed coefficients.
* The coefficients are reordered from zigzag order into natural array order, * The coefficients are reordered from zigzag order into natural array order,
@@ -433,18 +759,12 @@ process_restart (j_decompress_ptr cinfo)
* this module, since we'll just re-assign them on the next call.) * this module, since we'll just re-assign them on the next call.)
*/ */
METHODDEF boolean #define BUFSIZE (DCTSIZE2 * 2)
METHODDEF(boolean)
decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{ {
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; 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;
/* Process restart marker if needed; may have to suspend */ /* Process restart marker if needed; may have to suspend */
if (cinfo->restart_interval) { if (cinfo->restart_interval) {
@@ -453,96 +773,20 @@ decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
return FALSE; return FALSE;
} }
/* Load up working state */ /* If we've run out of data, just leave the MCU set to zeroes.
BITREAD_LOAD_STATE(cinfo,entropy->bitstate); * This way, we return uniform gray for the remainder of the segment.
ASSIGN_STATE(state, entropy->saved); */
if (! entropy->pub.insufficient_data) {
/* Outer loop handles each block in the MCU */ if (cinfo->src->bytes_in_buffer >= BUFSIZE) {
if (!decode_mcu_fast(cinfo, MCU_data)) return FALSE;
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { }
block = MCU_data[blkn]; else {
ci = cinfo->MCU_membership[blkn]; if (!decode_mcu_slow(cinfo, MCU_data)) return FALSE;
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);
} }
/* 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) */ /* Account for restart interval (no-op if not using restarts) */
entropy->restarts_to_go--; entropy->restarts_to_go--;
@@ -554,7 +798,7 @@ skip_ACs:
* Module initialization routine for Huffman entropy decoding. * Module initialization routine for Huffman entropy decoding.
*/ */
GLOBAL void GLOBAL(void)
jinit_huff_decoder (j_decompress_ptr cinfo) jinit_huff_decoder (j_decompress_ptr cinfo)
{ {
huff_entropy_ptr entropy; huff_entropy_ptr entropy;

View File

@@ -1,7 +1,7 @@
/* /*
* jdhuff.h * jdhuff.h
* *
* Copyright (C) 1991-1995, Thomas G. Lane. * Copyright (C) 1991-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -25,26 +25,34 @@
typedef struct { typedef struct {
/* Basic tables: (element [0] of each array is unused) */ /* 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) */ INT32 maxcode[18]; /* largest code of length k (-1 if none) */
/* (maxcode[17] is a sentinel to ensure jpeg_huff_decode terminates) */ /* (maxcode[17] is a sentinel to ensure jpeg_huff_decode terminates) */
int valptr[17]; /* huffval[] index of 1st symbol of length k */ INT32 valoffset[17]; /* 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) */ /* Link to public Huffman table (needed only in jpeg_huff_decode) */
JHUFF_TBL *pub; 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 * the input data stream. If the next Huffman code is no more
* than HUFF_LOOKAHEAD bits long, we can obtain its length and * 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 */ int lookup[1<<HUFF_LOOKAHEAD];
UINT8 look_sym[1<<HUFF_LOOKAHEAD]; /* symbol, or unused */
} d_derived_tbl; } d_derived_tbl;
/* Expand a Huffman table definition into the derived format */ /* Expand a Huffman table definition into the derived format */
EXTERN void jpeg_make_d_derived_tbl JPP((j_decompress_ptr cinfo, EXTERN(void) jpeg_make_d_derived_tbl
JHUFF_TBL * htbl, d_derived_tbl ** pdtbl)); JPP((j_decompress_ptr cinfo, boolean isDC, int tblno,
d_derived_tbl ** pdtbl));
/* /*
@@ -65,35 +73,42 @@ EXTERN void jpeg_make_d_derived_tbl JPP((j_decompress_ptr cinfo,
* necessary. * necessary.
*/ */
#if __WORDSIZE == 64
typedef long 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 */ 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 /* 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 * 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 * appropriately should be a win. Unfortunately we can't define the size
* something like #define BIT_BUF_SIZE (sizeof(bit_buf_type)*8) * with something like #define BIT_BUF_SIZE (sizeof(bit_buf_type)*8)
* because not all machines measure sizeof in 8-bit bytes. * because not all machines measure sizeof in 8-bit bytes.
*/ */
typedef struct { /* Bitreading state saved across MCUs */ typedef struct { /* Bitreading state saved across MCUs */
bit_buf_type get_buffer; /* current bit-extraction buffer */ bit_buf_type get_buffer; /* current bit-extraction buffer */
int bits_left; /* # of unused bits in it */ int bits_left; /* # of unused bits in it */
boolean printed_eod; /* flag to suppress multiple warning msgs */
} bitread_perm_state; } bitread_perm_state;
typedef struct { /* Bitreading working state within an MCU */ 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 */ const JOCTET * next_input_byte; /* => next byte to read from source */
size_t bytes_in_buffer; /* # of bytes remaining in source buffer */ 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. * not in this struct, inside the inner loops.
*/ */
bit_buf_type get_buffer; /* current bit-extraction buffer */ bit_buf_type get_buffer; /* current bit-extraction buffer */
int bits_left; /* # of unused bits in it */ 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 */ j_decompress_ptr cinfo; /* back link to decompress master record */
boolean * printed_eod_ptr; /* => flag in permanent state */
} bitread_working_state; } bitread_working_state;
/* Macros to declare and load/save bitread local variables. */ /* Macros to declare and load/save bitread local variables. */
@@ -106,15 +121,12 @@ typedef struct { /* Bitreading working state within an MCU */
br_state.cinfo = cinfop; \ br_state.cinfo = cinfop; \
br_state.next_input_byte = cinfop->src->next_input_byte; \ br_state.next_input_byte = cinfop->src->next_input_byte; \
br_state.bytes_in_buffer = cinfop->src->bytes_in_buffer; \ br_state.bytes_in_buffer = cinfop->src->bytes_in_buffer; \
br_state.unread_marker = cinfop->unread_marker; \
get_buffer = permstate.get_buffer; \ get_buffer = permstate.get_buffer; \
bits_left = permstate.bits_left; \ bits_left = permstate.bits_left;
br_state.printed_eod_ptr = & permstate.printed_eod
#define BITREAD_SAVE_STATE(cinfop,permstate) \ #define BITREAD_SAVE_STATE(cinfop,permstate) \
cinfop->src->next_input_byte = br_state.next_input_byte; \ cinfop->src->next_input_byte = br_state.next_input_byte; \
cinfop->src->bytes_in_buffer = br_state.bytes_in_buffer; \ cinfop->src->bytes_in_buffer = br_state.bytes_in_buffer; \
cinfop->unread_marker = br_state.unread_marker; \
permstate.get_buffer = get_buffer; \ permstate.get_buffer = get_buffer; \
permstate.bits_left = bits_left permstate.bits_left = bits_left
@@ -152,9 +164,9 @@ typedef struct { /* Bitreading working state within an MCU */
(bits_left -= (nbits)) (bits_left -= (nbits))
/* Load up the bit buffer to a depth of at least nbits */ /* Load up the bit buffer to a depth of at least nbits */
EXTERN boolean jpeg_fill_bit_buffer JPP((bitread_working_state * state, EXTERN(boolean) jpeg_fill_bit_buffer
register bit_buf_type get_buffer, register int bits_left, JPP((bitread_working_state * state, register bit_buf_type get_buffer,
int nbits)); register int bits_left, int nbits));
/* /*
@@ -184,11 +196,10 @@ EXTERN boolean jpeg_fill_bit_buffer JPP((bitread_working_state * state,
} \ } \
} \ } \
look = PEEK_BITS(HUFF_LOOKAHEAD); \ look = PEEK_BITS(HUFF_LOOKAHEAD); \
if ((nb = htbl->look_nbits[look]) != 0) { \ if ((nb = (htbl->lookup[look] >> HUFF_LOOKAHEAD)) <= HUFF_LOOKAHEAD) { \
DROP_BITS(nb); \ DROP_BITS(nb); \
result = htbl->look_sym[look]; \ result = htbl->lookup[look] & ((1 << HUFF_LOOKAHEAD) - 1); \
} else { \ } else { \
nb = HUFF_LOOKAHEAD+1; \
slowlabel: \ slowlabel: \
if ((result=jpeg_huff_decode(&state,get_buffer,bits_left,htbl,nb)) < 0) \ if ((result=jpeg_huff_decode(&state,get_buffer,bits_left,htbl,nb)) < 0) \
{ failaction; } \ { failaction; } \
@@ -197,6 +208,6 @@ slowlabel: \
} }
/* Out-of-line case for Huffman code fetching */ /* Out-of-line case for Huffman code fetching */
EXTERN int jpeg_huff_decode JPP((bitread_working_state * state, EXTERN(int) jpeg_huff_decode
register bit_buf_type get_buffer, register int bits_left, JPP((bitread_working_state * state, register bit_buf_type get_buffer,
d_derived_tbl * htbl, int min_bits)); register int bits_left, d_derived_tbl * htbl, int min_bits));

View File

@@ -1,7 +1,7 @@
/* /*
* jdinput.c * jdinput.c
* *
* Copyright (C) 1991-1995, Thomas G. Lane. * Copyright (C) 1991-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -28,14 +28,14 @@ typedef my_input_controller * my_inputctl_ptr;
/* Forward declarations */ /* Forward declarations */
METHODDEF int consume_markers JPP((j_decompress_ptr cinfo)); METHODDEF(int) consume_markers JPP((j_decompress_ptr cinfo));
/* /*
* Routines to calculate various quantities related to the size of the image. * Routines to calculate various quantities related to the size of the image.
*/ */
LOCAL void LOCAL(void)
initial_setup (j_decompress_ptr cinfo) initial_setup (j_decompress_ptr cinfo)
/* Called once, when first SOS marker is reached */ /* Called once, when first SOS marker is reached */
{ {
@@ -117,7 +117,7 @@ initial_setup (j_decompress_ptr cinfo)
} }
LOCAL void LOCAL(void)
per_scan_setup (j_decompress_ptr cinfo) per_scan_setup (j_decompress_ptr cinfo)
/* Do computations that are needed before processing a JPEG scan */ /* Do computations that are needed before processing a JPEG scan */
/* cinfo->comps_in_scan and cinfo->cur_comp_info[] were set from SOS marker */ /* cinfo->comps_in_scan and cinfo->cur_comp_info[] were set from SOS marker */
@@ -216,7 +216,7 @@ per_scan_setup (j_decompress_ptr cinfo)
* not at the current Q-table slots. * not at the current Q-table slots.
*/ */
LOCAL void LOCAL(void)
latch_quant_tables (j_decompress_ptr cinfo) latch_quant_tables (j_decompress_ptr cinfo)
{ {
int ci, qtblno; int ci, qtblno;
@@ -250,7 +250,7 @@ latch_quant_tables (j_decompress_ptr cinfo)
* Subsequent calls come from consume_markers, below. * Subsequent calls come from consume_markers, below.
*/ */
METHODDEF void METHODDEF(void)
start_input_pass (j_decompress_ptr cinfo) start_input_pass (j_decompress_ptr cinfo)
{ {
per_scan_setup(cinfo); per_scan_setup(cinfo);
@@ -267,7 +267,7 @@ start_input_pass (j_decompress_ptr cinfo)
* the expected data of the scan. * the expected data of the scan.
*/ */
METHODDEF void METHODDEF(void)
finish_input_pass (j_decompress_ptr cinfo) finish_input_pass (j_decompress_ptr cinfo)
{ {
cinfo->inputctl->consume_input = consume_markers; cinfo->inputctl->consume_input = consume_markers;
@@ -284,7 +284,7 @@ finish_input_pass (j_decompress_ptr cinfo)
* we are reading a compressed data segment or inter-segment markers. * we are reading a compressed data segment or inter-segment markers.
*/ */
METHODDEF int METHODDEF(int)
consume_markers (j_decompress_ptr cinfo) consume_markers (j_decompress_ptr cinfo)
{ {
my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl; my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl;
@@ -301,7 +301,7 @@ consume_markers (j_decompress_ptr cinfo)
initial_setup(cinfo); initial_setup(cinfo);
inputctl->inheaders = FALSE; inputctl->inheaders = FALSE;
/* Note: start_input_pass must be called by jdmaster.c /* 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. * responsible for enforcing this sequencing.
*/ */
} else { /* 2nd or later SOS marker */ } else { /* 2nd or later SOS marker */
@@ -335,7 +335,7 @@ consume_markers (j_decompress_ptr cinfo)
* Reset state to begin a fresh datastream. * Reset state to begin a fresh datastream.
*/ */
METHODDEF void METHODDEF(void)
reset_input_controller (j_decompress_ptr cinfo) reset_input_controller (j_decompress_ptr cinfo)
{ {
my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl; my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl;
@@ -357,7 +357,7 @@ reset_input_controller (j_decompress_ptr cinfo)
* This is called only once, when the decompression object is created. * This is called only once, when the decompression object is created.
*/ */
GLOBAL void GLOBAL(void)
jinit_input_controller (j_decompress_ptr cinfo) jinit_input_controller (j_decompress_ptr cinfo)
{ {
my_inputctl_ptr inputctl; my_inputctl_ptr inputctl;

View File

@@ -1,7 +1,7 @@
/* /*
* jdmainct.c * jdmainct.c
* *
* Copyright (C) 1994-1995, Thomas G. Lane. * Copyright (C) 1994-1996, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -140,20 +140,20 @@ typedef my_main_controller * my_main_ptr;
/* Forward declarations */ /* Forward declarations */
METHODDEF void process_data_simple_main METHODDEF(void) process_data_simple_main
JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf, JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)); JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
METHODDEF void process_data_context_main METHODDEF(void) process_data_context_main
JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf, JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)); JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
#ifdef QUANT_2PASS_SUPPORTED #ifdef QUANT_2PASS_SUPPORTED
METHODDEF void process_data_crank_post METHODDEF(void) process_data_crank_post
JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf, JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)); JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
#endif #endif
LOCAL void LOCAL(void)
alloc_funny_pointers (j_decompress_ptr cinfo) alloc_funny_pointers (j_decompress_ptr cinfo)
/* Allocate space for the funny pointer lists. /* Allocate space for the funny pointer lists.
* This is done only once, not once per pass. * This is done only once, not once per pass.
@@ -191,7 +191,7 @@ alloc_funny_pointers (j_decompress_ptr cinfo)
} }
LOCAL void LOCAL(void)
make_funny_pointers (j_decompress_ptr cinfo) make_funny_pointers (j_decompress_ptr cinfo)
/* Create the funny pointer lists discussed in the comments above. /* Create the funny pointer lists discussed in the comments above.
* The actual workspace is already allocated (in main->buffer), * The actual workspace is already allocated (in main->buffer),
@@ -234,7 +234,7 @@ make_funny_pointers (j_decompress_ptr cinfo)
} }
LOCAL void LOCAL(void)
set_wraparound_pointers (j_decompress_ptr cinfo) set_wraparound_pointers (j_decompress_ptr cinfo)
/* Set up the "wraparound" pointers at top and bottom of the pointer lists. /* Set up the "wraparound" pointers at top and bottom of the pointer lists.
* This changes the pointer list state from top-of-image to the normal state. * This changes the pointer list state from top-of-image to the normal state.
@@ -262,7 +262,7 @@ set_wraparound_pointers (j_decompress_ptr cinfo)
} }
LOCAL void LOCAL(void)
set_bottom_pointers (j_decompress_ptr cinfo) set_bottom_pointers (j_decompress_ptr cinfo)
/* Change the pointer lists to duplicate the last sample row at the bottom /* Change the pointer lists to duplicate the last sample row at the bottom
* of the image. whichptr indicates which xbuffer holds the final iMCU row. * of the image. whichptr indicates which xbuffer holds the final iMCU row.
@@ -303,7 +303,7 @@ set_bottom_pointers (j_decompress_ptr cinfo)
* Initialize for a processing pass. * Initialize for a processing pass.
*/ */
METHODDEF void METHODDEF(void)
start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode) start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
{ {
my_main_ptr main = (my_main_ptr) cinfo->main; my_main_ptr main = (my_main_ptr) cinfo->main;
@@ -341,7 +341,7 @@ start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
* This handles the simple case where no context is required. * This handles the simple case where no context is required.
*/ */
METHODDEF void METHODDEF(void)
process_data_simple_main (j_decompress_ptr cinfo, process_data_simple_main (j_decompress_ptr cinfo,
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
JDIMENSION out_rows_avail) JDIMENSION out_rows_avail)
@@ -381,7 +381,7 @@ process_data_simple_main (j_decompress_ptr cinfo,
* This handles the case where context rows must be provided. * This handles the case where context rows must be provided.
*/ */
METHODDEF void METHODDEF(void)
process_data_context_main (j_decompress_ptr cinfo, process_data_context_main (j_decompress_ptr cinfo,
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
JDIMENSION out_rows_avail) JDIMENSION out_rows_avail)
@@ -455,7 +455,7 @@ process_data_context_main (j_decompress_ptr cinfo,
#ifdef QUANT_2PASS_SUPPORTED #ifdef QUANT_2PASS_SUPPORTED
METHODDEF void METHODDEF(void)
process_data_crank_post (j_decompress_ptr cinfo, process_data_crank_post (j_decompress_ptr cinfo,
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
JDIMENSION out_rows_avail) JDIMENSION out_rows_avail)
@@ -472,7 +472,7 @@ process_data_crank_post (j_decompress_ptr cinfo,
* Initialize main buffer controller. * Initialize main buffer controller.
*/ */
GLOBAL void GLOBAL(void)
jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer) jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
{ {
my_main_ptr main; my_main_ptr main;

View File

@@ -1,7 +1,7 @@
/* /*
* jdmarker.c * jdmarker.c
* *
* Copyright (C) 1991-1995, Thomas G. Lane. * Copyright (C) 1991-1998, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -85,6 +85,28 @@ typedef enum { /* JPEG marker codes */
} JPEG_MARKER; } 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. * 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->next_input_byte = next_input_byte, \
datasrc->bytes_in_buffer = bytes_in_buffer ) 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) \ #define INPUT_RELOAD(cinfo) \
( next_input_byte = datasrc->next_input_byte, \ ( next_input_byte = datasrc->next_input_byte, \
bytes_in_buffer = datasrc->bytes_in_buffer ) bytes_in_buffer = datasrc->bytes_in_buffer )
@@ -118,14 +140,14 @@ typedef enum { /* JPEG marker codes */
if (! (*datasrc->fill_input_buffer) (cinfo)) \ if (! (*datasrc->fill_input_buffer) (cinfo)) \
{ action; } \ { action; } \
INPUT_RELOAD(cinfo); \ INPUT_RELOAD(cinfo); \
} \ }
bytes_in_buffer--
/* Read a byte into variable V. /* Read a byte into variable V.
* If must suspend, take the specified action (typically "return FALSE"). * If must suspend, take the specified action (typically "return FALSE").
*/ */
#define INPUT_BYTE(cinfo,V,action) \ #define INPUT_BYTE(cinfo,V,action) \
MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \ MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \
bytes_in_buffer--; \
V = GETJOCTET(*next_input_byte++); ) V = GETJOCTET(*next_input_byte++); )
/* As above, but read two bytes interpreted as an unsigned 16-bit integer. /* 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) \ #define INPUT_2BYTES(cinfo,V,action) \
MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \ MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \
bytes_in_buffer--; \
V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \ V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \
MAKE_BYTE_AVAIL(cinfo,action); \ MAKE_BYTE_AVAIL(cinfo,action); \
bytes_in_buffer--; \
V += GETJOCTET(*next_input_byte++); ) V += GETJOCTET(*next_input_byte++); )
@@ -150,11 +174,18 @@ typedef enum { /* JPEG marker codes */
* marker parameters; restart point has not been moved. Same routine * marker parameters; restart point has not been moved. Same routine
* will be called again after application supplies more input data. * will be called again after application supplies more input data.
* *
* This approach to suspension assumes that all of a marker's parameters can * This approach to suspension assumes that all of a marker's parameters
* fit into a single input bufferload. This should hold for "normal" * can fit into a single input bufferload. This should hold for "normal"
* markers. Some COM/APPn markers might have large parameter segments, * 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 * that might not fit. If we are simply dropping such a marker, we use
* on the source manager's shoulders. * 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 * Note that we don't bother to avoid duplicate trace messages if a
* suspension occurs within marker parameters. Other side effects * suspension occurs within marker parameters. Other side effects
@@ -162,7 +193,7 @@ typedef enum { /* JPEG marker codes */
*/ */
LOCAL boolean LOCAL(boolean)
get_soi (j_decompress_ptr cinfo) get_soi (j_decompress_ptr cinfo)
/* Process an SOI marker */ /* Process an SOI marker */
{ {
@@ -188,7 +219,9 @@ get_soi (j_decompress_ptr cinfo)
cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling??? */ cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling??? */
cinfo->saw_JFIF_marker = FALSE; 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->X_density = 1;
cinfo->Y_density = 1; cinfo->Y_density = 1;
cinfo->saw_Adobe_marker = FALSE; cinfo->saw_Adobe_marker = FALSE;
@@ -200,7 +233,7 @@ get_soi (j_decompress_ptr cinfo)
} }
LOCAL boolean LOCAL(boolean)
get_sof (j_decompress_ptr cinfo, boolean is_prog, boolean is_arith) get_sof (j_decompress_ptr cinfo, boolean is_prog, boolean is_arith)
/* Process a SOFn marker */ /* Process a SOFn marker */
{ {
@@ -264,7 +297,7 @@ get_sof (j_decompress_ptr cinfo, boolean is_prog, boolean is_arith)
} }
LOCAL boolean LOCAL(boolean)
get_sos (j_decompress_ptr cinfo) get_sos (j_decompress_ptr cinfo)
/* Process a SOS marker */ /* Process a SOS marker */
{ {
@@ -280,11 +313,11 @@ get_sos (j_decompress_ptr cinfo)
INPUT_BYTE(cinfo, n, return FALSE); /* Number of components */ 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) if (length != (n * 2 + 6) || n < 1 || n > MAX_COMPS_IN_SCAN)
ERREXIT(cinfo, JERR_BAD_LENGTH); ERREXIT(cinfo, JERR_BAD_LENGTH);
TRACEMS1(cinfo, 1, JTRC_SOS, n);
cinfo->comps_in_scan = n; cinfo->comps_in_scan = n;
/* Collect the component-spec parameters */ /* Collect the component-spec parameters */
@@ -334,113 +367,9 @@ get_sos (j_decompress_ptr cinfo)
} }
METHODDEF boolean #ifdef D_ARITH_CODING_SUPPORTED
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); LOCAL(boolean)
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;
}
LOCAL boolean
get_dac (j_decompress_ptr cinfo) get_dac (j_decompress_ptr cinfo)
/* Process a DAC marker */ /* Process a DAC marker */
{ {
@@ -472,12 +401,21 @@ get_dac (j_decompress_ptr cinfo)
} }
} }
if (length != 0)
ERREXIT(cinfo, JERR_BAD_LENGTH);
INPUT_SYNC(cinfo); INPUT_SYNC(cinfo);
return TRUE; return TRUE;
} }
#else /* ! D_ARITH_CODING_SUPPORTED */
LOCAL boolean #define get_dac(cinfo) skip_variable(cinfo)
#endif /* D_ARITH_CODING_SUPPORTED */
LOCAL(boolean)
get_dht (j_decompress_ptr cinfo) get_dht (j_decompress_ptr cinfo)
/* Process a DHT marker */ /* Process a DHT marker */
{ {
@@ -491,7 +429,7 @@ get_dht (j_decompress_ptr cinfo)
INPUT_2BYTES(cinfo, length, return FALSE); INPUT_2BYTES(cinfo, length, return FALSE);
length -= 2; length -= 2;
while (length > 0) { while (length > 16) {
INPUT_BYTE(cinfo, index, return FALSE); INPUT_BYTE(cinfo, index, return FALSE);
TRACEMS1(cinfo, 1, JTRC_DHT, index); 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[9], bits[10], bits[11], bits[12],
bits[13], bits[14], bits[15], bits[16]); 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) if (count > 256 || ((INT32) count) > length)
ERREXIT(cinfo, JERR_DHT_COUNTS); ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
INPUT_BYTE(cinfo, huffval[i], return FALSE); INPUT_BYTE(cinfo, huffval[i], return FALSE);
@@ -537,12 +478,15 @@ get_dht (j_decompress_ptr cinfo)
MEMCOPY((*htblptr)->huffval, huffval, SIZEOF((*htblptr)->huffval)); MEMCOPY((*htblptr)->huffval, huffval, SIZEOF((*htblptr)->huffval));
} }
if (length != 0)
ERREXIT(cinfo, JERR_BAD_LENGTH);
INPUT_SYNC(cinfo); INPUT_SYNC(cinfo);
return TRUE; return TRUE;
} }
LOCAL boolean LOCAL(boolean)
get_dqt (j_decompress_ptr cinfo) get_dqt (j_decompress_ptr cinfo)
/* Process a DQT marker */ /* Process a DQT marker */
{ {
@@ -574,27 +518,33 @@ get_dqt (j_decompress_ptr cinfo)
INPUT_2BYTES(cinfo, tmp, return FALSE); INPUT_2BYTES(cinfo, tmp, return FALSE);
else else
INPUT_BYTE(cinfo, tmp, return FALSE); INPUT_BYTE(cinfo, tmp, return FALSE);
quant_ptr->quantval[i] = (UINT16) tmp; /* We convert the zigzag-order table to natural array order. */
quant_ptr->quantval[jpeg_natural_order[i]] = (UINT16) tmp;
} }
for (i = 0; i < DCTSIZE2; i += 8) { if (cinfo->err->trace_level >= 2) {
TRACEMS8(cinfo, 2, JTRC_QUANTVALS, for (i = 0; i < DCTSIZE2; i += 8) {
quant_ptr->quantval[i ], quant_ptr->quantval[i+1], TRACEMS8(cinfo, 2, JTRC_QUANTVALS,
quant_ptr->quantval[i+2], quant_ptr->quantval[i+3], quant_ptr->quantval[i], quant_ptr->quantval[i+1],
quant_ptr->quantval[i+4], quant_ptr->quantval[i+5], quant_ptr->quantval[i+2], quant_ptr->quantval[i+3],
quant_ptr->quantval[i+6], quant_ptr->quantval[i+7]); quant_ptr->quantval[i+4], quant_ptr->quantval[i+5],
quant_ptr->quantval[i+6], quant_ptr->quantval[i+7]);
}
} }
length -= DCTSIZE2+1; length -= DCTSIZE2+1;
if (prec) length -= DCTSIZE2; if (prec) length -= DCTSIZE2;
} }
if (length != 0)
ERREXIT(cinfo, JERR_BAD_LENGTH);
INPUT_SYNC(cinfo); INPUT_SYNC(cinfo);
return TRUE; return TRUE;
} }
LOCAL boolean LOCAL(boolean)
get_dri (j_decompress_ptr cinfo) get_dri (j_decompress_ptr cinfo)
/* Process a DRI marker */ /* Process a DRI marker */
{ {
@@ -618,7 +568,280 @@ get_dri (j_decompress_ptr cinfo)
} }
METHODDEF boolean /*
* 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_variable (j_decompress_ptr cinfo)
/* Skip over an unknown or uninteresting variable-length marker */ /* Skip over an unknown or uninteresting variable-length marker */
{ {
@@ -626,11 +849,13 @@ skip_variable (j_decompress_ptr cinfo)
INPUT_VARS(cinfo); INPUT_VARS(cinfo);
INPUT_2BYTES(cinfo, length, return FALSE); INPUT_2BYTES(cinfo, length, return FALSE);
length -= 2;
TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, (int) length); TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, (int) length);
INPUT_SYNC(cinfo); /* do before skip_input_data */ 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; return TRUE;
} }
@@ -645,7 +870,7 @@ skip_variable (j_decompress_ptr cinfo)
* but it will never be 0 or FF. * but it will never be 0 or FF.
*/ */
LOCAL boolean LOCAL(boolean)
next_marker (j_decompress_ptr cinfo) next_marker (j_decompress_ptr cinfo)
{ {
int c; int c;
@@ -692,7 +917,7 @@ next_marker (j_decompress_ptr cinfo)
} }
LOCAL boolean LOCAL(boolean)
first_marker (j_decompress_ptr cinfo) first_marker (j_decompress_ptr cinfo)
/* Like next_marker, but used to obtain the initial SOI marker. */ /* Like next_marker, but used to obtain the initial SOI marker. */
/* For this marker, we do not allow preceding garbage or fill; otherwise, /* For this marker, we do not allow preceding garbage or fill; otherwise,
@@ -723,7 +948,7 @@ first_marker (j_decompress_ptr cinfo)
* JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
*/ */
METHODDEF int METHODDEF(int)
read_markers (j_decompress_ptr cinfo) read_markers (j_decompress_ptr cinfo)
{ {
/* Outer loop repeats once for each marker. */ /* Outer loop repeats once for each marker. */
@@ -830,12 +1055,13 @@ read_markers (j_decompress_ptr cinfo)
case M_APP13: case M_APP13:
case M_APP14: case M_APP14:
case M_APP15: 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; return JPEG_SUSPENDED;
break; break;
case M_COM: case M_COM:
if (! (*cinfo->marker->process_COM) (cinfo)) if (! (*((my_marker_ptr) cinfo->marker)->process_COM) (cinfo))
return JPEG_SUSPENDED; return JPEG_SUSPENDED;
break; break;
@@ -883,7 +1109,7 @@ read_markers (j_decompress_ptr cinfo)
* it holds a marker which the decoder will be unable to read past. * it holds a marker which the decoder will be unable to read past.
*/ */
METHODDEF boolean METHODDEF(boolean)
read_restart_marker (j_decompress_ptr cinfo) read_restart_marker (j_decompress_ptr cinfo)
{ {
/* Obtain a marker unless we already did. */ /* Obtain a marker unless we already did. */
@@ -896,7 +1122,7 @@ read_restart_marker (j_decompress_ptr cinfo)
if (cinfo->unread_marker == if (cinfo->unread_marker ==
((int) M_RST0 + cinfo->marker->next_restart_num)) { ((int) M_RST0 + cinfo->marker->next_restart_num)) {
/* Normal case --- swallow the marker and let entropy decoder continue */ /* Normal case --- swallow the marker and let entropy decoder continue */
TRACEMS1(cinfo, 2, JTRC_RST, cinfo->marker->next_restart_num); TRACEMS1(cinfo, 3, JTRC_RST, cinfo->marker->next_restart_num);
cinfo->unread_marker = 0; cinfo->unread_marker = 0;
} else { } else {
/* Uh-oh, the restart markers have been messed up. */ /* Uh-oh, the restart markers have been messed up. */
@@ -962,7 +1188,7 @@ read_restart_marker (j_decompress_ptr cinfo)
* any other marker would have to be bogus data in that case. * any other marker would have to be bogus data in that case.
*/ */
GLOBAL boolean GLOBAL(boolean)
jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired) jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired)
{ {
int marker = cinfo->unread_marker; int marker = cinfo->unread_marker;
@@ -1012,15 +1238,18 @@ jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired)
* Reset marker processing state to begin a fresh datastream. * Reset marker processing state to begin a fresh datastream.
*/ */
METHODDEF void METHODDEF(void)
reset_marker_reader (j_decompress_ptr cinfo) 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->comp_info = NULL; /* until allocated by get_sof */
cinfo->input_scan_number = 0; /* no SOS seen yet */ cinfo->input_scan_number = 0; /* no SOS seen yet */
cinfo->unread_marker = 0; /* no pending marker */ cinfo->unread_marker = 0; /* no pending marker */
cinfo->marker->saw_SOI = FALSE; /* set internal state too */ marker->pub.saw_SOI = FALSE; /* set internal state too */
cinfo->marker->saw_SOF = FALSE; marker->pub.saw_SOF = FALSE;
cinfo->marker->discarded_bytes = 0; marker->pub.discarded_bytes = 0;
marker->cur_marker = NULL;
} }
@@ -1029,24 +1258,103 @@ reset_marker_reader (j_decompress_ptr cinfo)
* This is called only once, when the decompression object is created. * This is called only once, when the decompression object is created.
*/ */
GLOBAL void GLOBAL(void)
jinit_marker_reader (j_decompress_ptr cinfo) jinit_marker_reader (j_decompress_ptr cinfo)
{ {
my_marker_ptr marker;
int i; int i;
/* Create subobject in permanent pool */ /* 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, (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
SIZEOF(struct jpeg_marker_reader)); SIZEOF(my_marker_reader));
/* Initialize method pointers */ cinfo->marker = (struct jpeg_marker_reader *) marker;
cinfo->marker->reset_marker_reader = reset_marker_reader; /* Initialize public method pointers */
cinfo->marker->read_markers = read_markers; marker->pub.reset_marker_reader = reset_marker_reader;
cinfo->marker->read_restart_marker = read_restart_marker; marker->pub.read_markers = read_markers;
cinfo->marker->process_COM = skip_variable; marker->pub.read_restart_marker = read_restart_marker;
for (i = 0; i < 16; i++) /* Initialize COM/APPn processing.
cinfo->marker->process_APPn[i] = skip_variable; * By default, we examine and then discard APP0 and APP14,
cinfo->marker->process_APPn[0] = get_app0; * but simply discard COM and all other APPn.
cinfo->marker->process_APPn[14] = get_app14; */
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 processing state */
reset_marker_reader(cinfo); 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 * jdmaster.c
* *
* Copyright (C) 1991-1995, 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. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -40,7 +41,7 @@ typedef my_decomp_master * my_master_ptr;
* CRUCIAL: this must match the actual capabilities of jdmerge.c! * CRUCIAL: this must match the actual capabilities of jdmerge.c!
*/ */
LOCAL boolean LOCAL(boolean)
use_merged_upsample (j_decompress_ptr cinfo) use_merged_upsample (j_decompress_ptr cinfo)
{ {
#ifdef UPSAMPLE_MERGING_SUPPORTED #ifdef UPSAMPLE_MERGING_SUPPORTED
@@ -49,8 +50,14 @@ use_merged_upsample (j_decompress_ptr cinfo)
return FALSE; return FALSE;
/* jdmerge.c only supports YCC=>RGB color conversion */ /* jdmerge.c only supports YCC=>RGB color conversion */
if (cinfo->jpeg_color_space != JCS_YCbCr || cinfo->num_components != 3 || if (cinfo->jpeg_color_space != JCS_YCbCr || cinfo->num_components != 3 ||
cinfo->out_color_space != JCS_RGB || (cinfo->out_color_space != JCS_RGB &&
cinfo->out_color_components != RGB_PIXELSIZE) 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; return FALSE;
/* and it only handles 2h1v or 2h2v sampling ratios */ /* and it only handles 2h1v or 2h2v sampling ratios */
if (cinfo->comp_info[0].h_samp_factor != 2 || if (cinfo->comp_info[0].h_samp_factor != 2 ||
@@ -80,12 +87,14 @@ use_merged_upsample (j_decompress_ptr cinfo)
* Also note that it may be called before the master module is initialized! * Also note that it may be called before the master module is initialized!
*/ */
GLOBAL void GLOBAL(void)
jpeg_calc_output_dimensions (j_decompress_ptr cinfo) jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
/* Do computations that are needed before master selection phase */ /* Do computations that are needed before master selection phase */
{ {
#ifdef IDCT_SCALING_SUPPORTED
int ci; int ci;
jpeg_component_info *compptr; jpeg_component_info *compptr;
#endif
/* Prevent application from calling me at wrong times */ /* Prevent application from calling me at wrong times */
if (cinfo->global_state != DSTATE_READY) if (cinfo->global_state != DSTATE_READY)
@@ -173,10 +182,14 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
cinfo->out_color_components = 1; cinfo->out_color_components = 1;
break; break;
case JCS_RGB: case JCS_RGB:
#if RGB_PIXELSIZE != 3 case JCS_EXT_RGB:
cinfo->out_color_components = RGB_PIXELSIZE; 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; break;
#endif /* else share code with YCbCr */
case JCS_YCbCr: case JCS_YCbCr:
cinfo->out_color_components = 3; cinfo->out_color_components = 3;
break; break;
@@ -242,7 +255,7 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
* enough and used often enough to justify this. * enough and used often enough to justify this.
*/ */
LOCAL void LOCAL(void)
prepare_range_limit_table (j_decompress_ptr cinfo) prepare_range_limit_table (j_decompress_ptr cinfo)
/* Allocate and fill in the sample_range_limit table */ /* Allocate and fill in the sample_range_limit table */
{ {
@@ -282,7 +295,7 @@ prepare_range_limit_table (j_decompress_ptr cinfo)
* settings. * settings.
*/ */
LOCAL void LOCAL(void)
master_selection (j_decompress_ptr cinfo) master_selection (j_decompress_ptr cinfo)
{ {
my_master_ptr master = (my_master_ptr) cinfo->master; my_master_ptr master = (my_master_ptr) cinfo->master;
@@ -429,10 +442,10 @@ master_selection (j_decompress_ptr cinfo)
* modules will be active during this pass and give them appropriate * modules will be active during this pass and give them appropriate
* start_pass calls. We also set is_dummy_pass to indicate whether this * 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. * 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 METHODDEF(void)
prepare_for_output_pass (j_decompress_ptr cinfo) prepare_for_output_pass (j_decompress_ptr cinfo)
{ {
my_master_ptr master = (my_master_ptr) cinfo->master; my_master_ptr master = (my_master_ptr) cinfo->master;
@@ -492,7 +505,7 @@ prepare_for_output_pass (j_decompress_ptr cinfo)
* Finish up at end of an output pass. * Finish up at end of an output pass.
*/ */
METHODDEF void METHODDEF(void)
finish_output_pass (j_decompress_ptr cinfo) finish_output_pass (j_decompress_ptr cinfo)
{ {
my_master_ptr master = (my_master_ptr) cinfo->master; my_master_ptr master = (my_master_ptr) cinfo->master;
@@ -509,7 +522,7 @@ finish_output_pass (j_decompress_ptr cinfo)
* Switch to a new external colormap between output passes. * Switch to a new external colormap between output passes.
*/ */
GLOBAL void GLOBAL(void)
jpeg_new_colormap (j_decompress_ptr cinfo) jpeg_new_colormap (j_decompress_ptr cinfo)
{ {
my_master_ptr master = (my_master_ptr) cinfo->master; my_master_ptr master = (my_master_ptr) cinfo->master;
@@ -537,7 +550,7 @@ jpeg_new_colormap (j_decompress_ptr cinfo)
* This is performed at the start of jpeg_start_decompress. * This is performed at the start of jpeg_start_decompress.
*/ */
GLOBAL void GLOBAL(void)
jinit_master_decompress (j_decompress_ptr cinfo) jinit_master_decompress (j_decompress_ptr cinfo)
{ {
my_master_ptr master; my_master_ptr master;

View File

@@ -1,7 +1,9 @@
/* /*
* jdmerge.c * jdmerge.c
* *
* Copyright (C) 1994-1995, Thomas G. Lane. * 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. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -35,6 +37,7 @@
#define JPEG_INTERNALS #define JPEG_INTERNALS
#include "jinclude.h" #include "jinclude.h"
#include "jpeglib.h" #include "jpeglib.h"
#include "jsimd.h"
#ifdef UPSAMPLE_MERGING_SUPPORTED #ifdef UPSAMPLE_MERGING_SUPPORTED
@@ -79,7 +82,7 @@ typedef my_upsampler * my_upsample_ptr;
* This is taken directly from jdcolor.c; see that file for more info. * This is taken directly from jdcolor.c; see that file for more info.
*/ */
LOCAL void LOCAL(void)
build_ycc_rgb_table (j_decompress_ptr cinfo) build_ycc_rgb_table (j_decompress_ptr cinfo)
{ {
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
@@ -122,7 +125,7 @@ build_ycc_rgb_table (j_decompress_ptr cinfo)
* Initialize for an upsampling pass. * Initialize for an upsampling pass.
*/ */
METHODDEF void METHODDEF(void)
start_pass_merged_upsample (j_decompress_ptr cinfo) start_pass_merged_upsample (j_decompress_ptr cinfo)
{ {
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
@@ -140,7 +143,7 @@ start_pass_merged_upsample (j_decompress_ptr cinfo)
* The control routine just handles the row buffering considerations. * The control routine just handles the row buffering considerations.
*/ */
METHODDEF void METHODDEF(void)
merged_2v_upsample (j_decompress_ptr cinfo, merged_2v_upsample (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
JDIMENSION in_row_groups_avail, JDIMENSION in_row_groups_avail,
@@ -189,7 +192,7 @@ merged_2v_upsample (j_decompress_ptr cinfo,
} }
METHODDEF void METHODDEF(void)
merged_1v_upsample (j_decompress_ptr cinfo, merged_1v_upsample (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
JDIMENSION in_row_groups_avail, JDIMENSION in_row_groups_avail,
@@ -222,7 +225,7 @@ merged_1v_upsample (j_decompress_ptr cinfo,
* Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical. * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
*/ */
METHODDEF void METHODDEF(void)
h2v1_merged_upsample (j_decompress_ptr cinfo, h2v1_merged_upsample (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
JSAMPARRAY output_buf) JSAMPARRAY output_buf)
@@ -255,15 +258,15 @@ h2v1_merged_upsample (j_decompress_ptr cinfo,
cblue = Cbbtab[cb]; cblue = Cbbtab[cb];
/* Fetch 2 Y values and emit 2 pixels */ /* Fetch 2 Y values and emit 2 pixels */
y = GETJSAMPLE(*inptr0++); y = GETJSAMPLE(*inptr0++);
outptr[RGB_RED] = range_limit[y + cred]; outptr[rgb_red[cinfo->out_color_space]] = range_limit[y + cred];
outptr[RGB_GREEN] = range_limit[y + cgreen]; outptr[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
outptr[RGB_BLUE] = range_limit[y + cblue]; outptr[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
outptr += RGB_PIXELSIZE; outptr += rgb_pixelsize[cinfo->out_color_space];
y = GETJSAMPLE(*inptr0++); y = GETJSAMPLE(*inptr0++);
outptr[RGB_RED] = range_limit[y + cred]; outptr[rgb_red[cinfo->out_color_space]] = range_limit[y + cred];
outptr[RGB_GREEN] = range_limit[y + cgreen]; outptr[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
outptr[RGB_BLUE] = range_limit[y + cblue]; outptr[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
outptr += RGB_PIXELSIZE; outptr += rgb_pixelsize[cinfo->out_color_space];
} }
/* If image width is odd, do the last output column separately */ /* If image width is odd, do the last output column separately */
if (cinfo->output_width & 1) { 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); cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
cblue = Cbbtab[cb]; cblue = Cbbtab[cb];
y = GETJSAMPLE(*inptr0); y = GETJSAMPLE(*inptr0);
outptr[RGB_RED] = range_limit[y + cred]; outptr[rgb_red[cinfo->out_color_space]] = range_limit[y + cred];
outptr[RGB_GREEN] = range_limit[y + cgreen]; outptr[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
outptr[RGB_BLUE] = range_limit[y + cblue]; outptr[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
} }
} }
@@ -284,7 +287,7 @@ h2v1_merged_upsample (j_decompress_ptr cinfo,
* Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical. * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
*/ */
METHODDEF void METHODDEF(void)
h2v2_merged_upsample (j_decompress_ptr cinfo, h2v2_merged_upsample (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
JSAMPARRAY output_buf) JSAMPARRAY output_buf)
@@ -319,24 +322,24 @@ h2v2_merged_upsample (j_decompress_ptr cinfo,
cblue = Cbbtab[cb]; cblue = Cbbtab[cb];
/* Fetch 4 Y values and emit 4 pixels */ /* Fetch 4 Y values and emit 4 pixels */
y = GETJSAMPLE(*inptr00++); y = GETJSAMPLE(*inptr00++);
outptr0[RGB_RED] = range_limit[y + cred]; outptr0[rgb_red[cinfo->out_color_space]] = range_limit[y + cred];
outptr0[RGB_GREEN] = range_limit[y + cgreen]; outptr0[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
outptr0[RGB_BLUE] = range_limit[y + cblue]; outptr0[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
outptr0 += RGB_PIXELSIZE; outptr0 += RGB_PIXELSIZE;
y = GETJSAMPLE(*inptr00++); y = GETJSAMPLE(*inptr00++);
outptr0[RGB_RED] = range_limit[y + cred]; outptr0[rgb_red[cinfo->out_color_space]] = range_limit[y + cred];
outptr0[RGB_GREEN] = range_limit[y + cgreen]; outptr0[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
outptr0[RGB_BLUE] = range_limit[y + cblue]; outptr0[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
outptr0 += RGB_PIXELSIZE; outptr0 += RGB_PIXELSIZE;
y = GETJSAMPLE(*inptr01++); y = GETJSAMPLE(*inptr01++);
outptr1[RGB_RED] = range_limit[y + cred]; outptr1[rgb_red[cinfo->out_color_space]] = range_limit[y + cred];
outptr1[RGB_GREEN] = range_limit[y + cgreen]; outptr1[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
outptr1[RGB_BLUE] = range_limit[y + cblue]; outptr1[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
outptr1 += RGB_PIXELSIZE; outptr1 += RGB_PIXELSIZE;
y = GETJSAMPLE(*inptr01++); y = GETJSAMPLE(*inptr01++);
outptr1[RGB_RED] = range_limit[y + cred]; outptr1[rgb_red[cinfo->out_color_space]] = range_limit[y + cred];
outptr1[RGB_GREEN] = range_limit[y + cgreen]; outptr1[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
outptr1[RGB_BLUE] = range_limit[y + cblue]; outptr1[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
outptr1 += RGB_PIXELSIZE; outptr1 += RGB_PIXELSIZE;
} }
/* If image width is odd, do the last output column separately */ /* 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); cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
cblue = Cbbtab[cb]; cblue = Cbbtab[cb];
y = GETJSAMPLE(*inptr00); y = GETJSAMPLE(*inptr00);
outptr0[RGB_RED] = range_limit[y + cred]; outptr0[rgb_red[cinfo->out_color_space]] = range_limit[y + cred];
outptr0[RGB_GREEN] = range_limit[y + cgreen]; outptr0[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
outptr0[RGB_BLUE] = range_limit[y + cblue]; outptr0[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
y = GETJSAMPLE(*inptr01); y = GETJSAMPLE(*inptr01);
outptr1[RGB_RED] = range_limit[y + cred]; outptr1[rgb_red[cinfo->out_color_space]] = range_limit[y + cred];
outptr1[RGB_GREEN] = range_limit[y + cgreen]; outptr1[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
outptr1[RGB_BLUE] = range_limit[y + cblue]; outptr1[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
} }
} }
@@ -366,7 +369,7 @@ h2v2_merged_upsample (j_decompress_ptr cinfo,
* of this module; no safety checks are made here. * of this module; no safety checks are made here.
*/ */
GLOBAL void GLOBAL(void)
jinit_merged_upsampler (j_decompress_ptr cinfo) jinit_merged_upsampler (j_decompress_ptr cinfo)
{ {
my_upsample_ptr upsample; my_upsample_ptr upsample;
@@ -382,14 +385,20 @@ jinit_merged_upsampler (j_decompress_ptr cinfo)
if (cinfo->max_v_samp_factor == 2) { if (cinfo->max_v_samp_factor == 2) {
upsample->pub.upsample = merged_2v_upsample; 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 */ /* Allocate a spare row buffer */
upsample->spare_row = (JSAMPROW) upsample->spare_row = (JSAMPROW)
(*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(size_t) (upsample->out_row_width * SIZEOF(JSAMPLE))); (size_t) (upsample->out_row_width * SIZEOF(JSAMPLE)));
} else { } else {
upsample->pub.upsample = merged_1v_upsample; 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 */ /* No spare row needed */
upsample->spare_row = NULL; upsample->spare_row = NULL;
} }

360
jdphuff.c
View File

@@ -1,7 +1,7 @@
/* /*
* jdphuff.c * jdphuff.c
* *
* Copyright (C) 1995, Thomas G. Lane. * Copyright (C) 1995-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -74,21 +74,21 @@ typedef struct {
typedef phuff_entropy_decoder * phuff_entropy_ptr; typedef phuff_entropy_decoder * phuff_entropy_ptr;
/* Forward declarations */ /* Forward declarations */
METHODDEF boolean decode_mcu_DC_first JPP((j_decompress_ptr cinfo, METHODDEF(boolean) decode_mcu_DC_first JPP((j_decompress_ptr cinfo,
JBLOCKROW *MCU_data));
METHODDEF boolean decode_mcu_AC_first JPP((j_decompress_ptr cinfo,
JBLOCKROW *MCU_data));
METHODDEF boolean decode_mcu_DC_refine JPP((j_decompress_ptr cinfo,
JBLOCKROW *MCU_data)); JBLOCKROW *MCU_data));
METHODDEF boolean decode_mcu_AC_refine JPP((j_decompress_ptr cinfo, METHODDEF(boolean) decode_mcu_AC_first JPP((j_decompress_ptr cinfo,
JBLOCKROW *MCU_data)); JBLOCKROW *MCU_data));
METHODDEF(boolean) decode_mcu_DC_refine JPP((j_decompress_ptr cinfo,
JBLOCKROW *MCU_data));
METHODDEF(boolean) decode_mcu_AC_refine JPP((j_decompress_ptr cinfo,
JBLOCKROW *MCU_data));
/* /*
* Initialize for a Huffman-compressed scan. * Initialize for a Huffman-compressed scan.
*/ */
METHODDEF void METHODDEF(void)
start_pass_phuff_decoder (j_decompress_ptr cinfo) start_pass_phuff_decoder (j_decompress_ptr cinfo)
{ {
phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
@@ -119,6 +119,12 @@ start_pass_phuff_decoder (j_decompress_ptr cinfo)
} }
if (cinfo->Al > 13) /* need not check for < 0 */ if (cinfo->Al > 13) /* need not check for < 0 */
bad = TRUE; 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) if (bad)
ERREXIT4(cinfo, JERR_BAD_PROGRESSION, ERREXIT4(cinfo, JERR_BAD_PROGRESSION,
cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al); 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 (is_DC_band) {
if (cinfo->Ah == 0) { /* DC refinement needs no table */ if (cinfo->Ah == 0) { /* DC refinement needs no table */
tbl = compptr->dc_tbl_no; tbl = compptr->dc_tbl_no;
if (tbl < 0 || tbl >= NUM_HUFF_TBLS || jpeg_make_d_derived_tbl(cinfo, TRUE, tbl,
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],
& entropy->derived_tbls[tbl]); & entropy->derived_tbls[tbl]);
} }
} else { } else {
tbl = compptr->ac_tbl_no; tbl = compptr->ac_tbl_no;
if (tbl < 0 || tbl >= NUM_HUFF_TBLS || jpeg_make_d_derived_tbl(cinfo, FALSE, tbl,
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],
& entropy->derived_tbls[tbl]); & entropy->derived_tbls[tbl]);
/* remember the single active table */ /* remember the single active table */
entropy->ac_derived_tbl = entropy->derived_tbls[tbl]; entropy->ac_derived_tbl = entropy->derived_tbls[tbl];
@@ -183,7 +183,7 @@ start_pass_phuff_decoder (j_decompress_ptr cinfo)
/* Initialize bitread state variables */ /* Initialize bitread state variables */
entropy->bitstate.bits_left = 0; entropy->bitstate.bits_left = 0;
entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */ entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */
entropy->bitstate.printed_eod = FALSE; entropy->pub.insufficient_data = FALSE;
/* Initialize private state variables */ /* Initialize private state variables */
entropy->saved.EOBRUN = 0; entropy->saved.EOBRUN = 0;
@@ -224,7 +224,7 @@ static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */
* Returns FALSE if must suspend. * Returns FALSE if must suspend.
*/ */
LOCAL boolean LOCAL(boolean)
process_restart (j_decompress_ptr cinfo) process_restart (j_decompress_ptr cinfo)
{ {
phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
@@ -248,8 +248,13 @@ process_restart (j_decompress_ptr cinfo)
/* Reset restart counter */ /* Reset restart counter */
entropy->restarts_to_go = cinfo->restart_interval; entropy->restarts_to_go = cinfo->restart_interval;
/* Next segment can get another out-of-data warning */ /* Reset out-of-data flag, unless read_restart_marker left us smack up
entropy->bitstate.printed_eod = FALSE; * 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; return TRUE;
} }
@@ -277,7 +282,7 @@ process_restart (j_decompress_ptr cinfo)
* or first pass of successive approximation). * or first pass of successive approximation).
*/ */
METHODDEF boolean METHODDEF(boolean)
decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{ {
phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
@@ -297,39 +302,45 @@ decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
return FALSE; return FALSE;
} }
/* Load up working state */ /* If we've run out of data, just leave the MCU set to zeroes.
BITREAD_LOAD_STATE(cinfo,entropy->bitstate); * This way, we return uniform gray for the remainder of the segment.
ASSIGN_STATE(state, entropy->saved); */
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++) { /* Outer loop handles each block in the MCU */
block = MCU_data[blkn];
ci = cinfo->MCU_membership[blkn];
compptr = cinfo->cur_comp_info[ci];
tbl = entropy->derived_tbls[compptr->dc_tbl_no];
/* 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 */ /* Decode a single block's worth of coefficients */
HUFF_DECODE(s, br_state, tbl, return FALSE, label1);
if (s) { /* Section F.2.2.1: decode the DC coefficient difference */
CHECK_BIT_BUFFER(br_state, s, return FALSE); HUFF_DECODE(s, br_state, tbl, return FALSE, label1);
r = GET_BITS(s); if (s) {
s = HUFF_EXTEND(r, 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 */ /* Completed MCU, so update state */
s += state.last_dc_val[ci]; BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
state.last_dc_val[ci] = s; ASSIGN_STATE(entropy->saved, state);
/* 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);
/* Account for restart interval (no-op if not using restarts) */ /* Account for restart interval (no-op if not using restarts) */
entropy->restarts_to_go--; entropy->restarts_to_go--;
@@ -342,7 +353,7 @@ decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
* or first pass of successive approximation). * or first pass of successive approximation).
*/ */
METHODDEF boolean METHODDEF(boolean)
decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{ {
phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
@@ -361,53 +372,59 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
return FALSE; return FALSE;
} }
/* Load up working state. /* If we've run out of data, just leave the MCU set to zeroes.
* We can avoid loading/saving bitread state if in an EOB run. * 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... */ /* There is always only one block per MCU */
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++) { if (EOBRUN > 0) /* if it's a band of zeroes... */
HUFF_DECODE(s, br_state, tbl, return FALSE, label2); EOBRUN--; /* ...process it now (we do nothing) */
r = s >> 4; else {
s &= 15; BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
if (s) { block = MCU_data[0];
k += r; tbl = entropy->ac_derived_tbl;
CHECK_BIT_BUFFER(br_state, s, return FALSE);
r = GET_BITS(s); for (k = cinfo->Ss; k <= Se; k++) {
s = HUFF_EXTEND(r, s); HUFF_DECODE(s, br_state, tbl, return FALSE, label2);
/* Scale and output coefficient in natural (dezigzagged) order */ r = s >> 4;
(*block)[jpeg_natural_order[k]] = (JCOEF) (s << Al); s &= 15;
} else { if (s) {
if (r == 15) { /* ZRL */ k += r;
k += 15; /* skip 15 zeroes in band */ CHECK_BIT_BUFFER(br_state, s, return FALSE);
} else { /* EOBr, run length is 2^r + appended bits */ r = GET_BITS(s);
EOBRUN = 1 << r; s = HUFF_EXTEND(r, s);
if (r) { /* EOBr, r > 0 */ /* Scale and output coefficient in natural (dezigzagged) order */
CHECK_BIT_BUFFER(br_state, r, return FALSE); (*block)[jpeg_natural_order[k]] = (JCOEF) (s << Al);
r = GET_BITS(r); } else {
EOBRUN += r; if (r == 15) { /* ZRL */
} k += 15; /* skip 15 zeroes in band */
EOBRUN--; /* this band is processed at this moment */ } else { /* EOBr, run length is 2^r + appended bits */
break; /* force end-of-band */ 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) */ /* Account for restart interval (no-op if not using restarts) */
entropy->restarts_to_go--; entropy->restarts_to_go--;
@@ -421,7 +438,7 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
* is not very clear on the point. * is not very clear on the point.
*/ */
METHODDEF boolean METHODDEF(boolean)
decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{ {
phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
@@ -437,6 +454,10 @@ decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
return FALSE; 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 */ /* Load up working state */
BITREAD_LOAD_STATE(cinfo,entropy->bitstate); BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
@@ -466,7 +487,7 @@ decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
* MCU decoding for AC successive approximation refinement scan. * MCU decoding for AC successive approximation refinement scan.
*/ */
METHODDEF boolean METHODDEF(boolean)
decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{ {
phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
@@ -489,55 +510,93 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
return FALSE; return FALSE;
} }
/* Load up working state */ /* If we've run out of data, don't modify the MCU.
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.
*/ */
num_newnz = 0; if (! entropy->pub.insufficient_data) {
/* initialize coefficient loop counter to start of band */ /* Load up working state */
k = cinfo->Ss; BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we need */
if (EOBRUN == 0) { /* There is always only one block per MCU */
for (; k <= Se; k++) { block = MCU_data[0];
HUFF_DECODE(s, br_state, tbl, goto undoit, label3); tbl = entropy->ac_derived_tbl;
r = s >> 4;
s &= 15; /* If we are forced to suspend, we must undo the assignments to any newly
if (s) { * nonzero coefficients in the block, because otherwise we'd get confused
if (s != 1) /* size of new coef should always be 1 */ * next time about which coefficients were already nonzero.
WARNMS(cinfo, JWRN_HUFF_BAD_CODE); * But we need not undo addition of bits to already-nonzero coefficients;
CHECK_BIT_BUFFER(br_state, 1, goto undoit); * instead, we can test the current bit to see if we already did it.
if (GET_BITS(1)) */
s = p1; /* newly nonzero coef is positive */ num_newnz = 0;
else
s = m1; /* newly nonzero coef is negative */ /* initialize coefficient loop counter to start of band */
} else { k = cinfo->Ss;
if (r != 15) {
EOBRUN = 1 << r; /* EOBr, run length is 2^r + appended bits */ if (EOBRUN == 0) {
if (r) { for (; k <= Se; k++) {
CHECK_BIT_BUFFER(br_state, r, goto undoit); HUFF_DECODE(s, br_state, tbl, goto undoit, label3);
r = GET_BITS(r); r = s >> 4;
EOBRUN += r; 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. * if the absolute value of the coefficient must be increased.
*/ */
do { for (; k <= Se; k++) {
thiscoef = *block + jpeg_natural_order[k]; thiscoef = *block + jpeg_natural_order[k];
if (*thiscoef != 0) { if (*thiscoef != 0) {
CHECK_BIT_BUFFER(br_state, 1, goto undoit); 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; *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 */ /* Completed MCU, so update state */
BITREAD_SAVE_STATE(cinfo,entropy->bitstate); BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we care about */ entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */
}
/* Account for restart interval (no-op if not using restarts) */ /* Account for restart interval (no-op if not using restarts) */
entropy->restarts_to_go--; entropy->restarts_to_go--;
@@ -611,7 +637,7 @@ undoit:
* Module initialization routine for progressive Huffman entropy decoding. * Module initialization routine for progressive Huffman entropy decoding.
*/ */
GLOBAL void GLOBAL(void)
jinit_phuff_decoder (j_decompress_ptr cinfo) jinit_phuff_decoder (j_decompress_ptr cinfo)
{ {
phuff_entropy_ptr entropy; phuff_entropy_ptr entropy;

View File

@@ -1,7 +1,7 @@
/* /*
* jdpostct.c * jdpostct.c
* *
* Copyright (C) 1994-1995, Thomas G. Lane. * Copyright (C) 1994-1996, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -43,20 +43,20 @@ typedef my_post_controller * my_post_ptr;
/* Forward declarations */ /* Forward declarations */
METHODDEF void post_process_1pass METHODDEF(void) post_process_1pass
JPP((j_decompress_ptr cinfo, JPP((j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
JDIMENSION in_row_groups_avail, JDIMENSION in_row_groups_avail,
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
JDIMENSION out_rows_avail)); JDIMENSION out_rows_avail));
#ifdef QUANT_2PASS_SUPPORTED #ifdef QUANT_2PASS_SUPPORTED
METHODDEF void post_process_prepass METHODDEF(void) post_process_prepass
JPP((j_decompress_ptr cinfo, JPP((j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
JDIMENSION in_row_groups_avail, JDIMENSION in_row_groups_avail,
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
JDIMENSION out_rows_avail)); JDIMENSION out_rows_avail));
METHODDEF void post_process_2pass METHODDEF(void) post_process_2pass
JPP((j_decompress_ptr cinfo, JPP((j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
JDIMENSION in_row_groups_avail, JDIMENSION in_row_groups_avail,
@@ -69,7 +69,7 @@ METHODDEF void post_process_2pass
* Initialize for a processing pass. * Initialize for a processing pass.
*/ */
METHODDEF void METHODDEF(void)
start_pass_dpost (j_decompress_ptr cinfo, J_BUF_MODE pass_mode) start_pass_dpost (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
{ {
my_post_ptr post = (my_post_ptr) cinfo->post; my_post_ptr post = (my_post_ptr) cinfo->post;
@@ -122,7 +122,7 @@ start_pass_dpost (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
* This is used for color precision reduction as well as one-pass quantization. * This is used for color precision reduction as well as one-pass quantization.
*/ */
METHODDEF void METHODDEF(void)
post_process_1pass (j_decompress_ptr cinfo, post_process_1pass (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
JDIMENSION in_row_groups_avail, JDIMENSION in_row_groups_avail,
@@ -154,7 +154,7 @@ post_process_1pass (j_decompress_ptr cinfo,
* Process some data in the first pass of 2-pass quantization. * Process some data in the first pass of 2-pass quantization.
*/ */
METHODDEF void METHODDEF(void)
post_process_prepass (j_decompress_ptr cinfo, post_process_prepass (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
JDIMENSION in_row_groups_avail, JDIMENSION in_row_groups_avail,
@@ -198,7 +198,7 @@ post_process_prepass (j_decompress_ptr cinfo,
* Process some data in the second pass of 2-pass quantization. * Process some data in the second pass of 2-pass quantization.
*/ */
METHODDEF void METHODDEF(void)
post_process_2pass (j_decompress_ptr cinfo, post_process_2pass (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
JDIMENSION in_row_groups_avail, JDIMENSION in_row_groups_avail,
@@ -246,7 +246,7 @@ post_process_2pass (j_decompress_ptr cinfo,
* Initialize postprocessing controller. * Initialize postprocessing controller.
*/ */
GLOBAL void GLOBAL(void)
jinit_d_post_controller (j_decompress_ptr cinfo, boolean need_full_buffer) jinit_d_post_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
{ {
my_post_ptr post; my_post_ptr post;

View File

@@ -1,7 +1,8 @@
/* /*
* jdsample.c * jdsample.c
* *
* Copyright (C) 1991-1994, Thomas G. Lane. * 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. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -21,6 +22,7 @@
#define JPEG_INTERNALS #define JPEG_INTERNALS
#include "jinclude.h" #include "jinclude.h"
#include "jpeglib.h" #include "jpeglib.h"
#include "jsimd.h"
/* Pointer to routine to upsample a single component */ /* Pointer to routine to upsample a single component */
@@ -65,7 +67,7 @@ typedef my_upsampler * my_upsample_ptr;
* Initialize for an upsampling pass. * Initialize for an upsampling pass.
*/ */
METHODDEF void METHODDEF(void)
start_pass_upsample (j_decompress_ptr cinfo) start_pass_upsample (j_decompress_ptr cinfo)
{ {
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
@@ -85,7 +87,7 @@ start_pass_upsample (j_decompress_ptr cinfo)
* color conversion a row at a time. * color conversion a row at a time.
*/ */
METHODDEF void METHODDEF(void)
sep_upsample (j_decompress_ptr cinfo, sep_upsample (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
JDIMENSION in_row_groups_avail, JDIMENSION in_row_groups_avail,
@@ -153,7 +155,7 @@ sep_upsample (j_decompress_ptr cinfo,
* "consumed" until we are done color converting and emitting it. * "consumed" until we are done color converting and emitting it.
*/ */
METHODDEF void METHODDEF(void)
fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
{ {
@@ -166,7 +168,7 @@ fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
* These components will not be referenced by color conversion. * These components will not be referenced by color conversion.
*/ */
METHODDEF void METHODDEF(void)
noop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, noop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
{ {
@@ -185,7 +187,7 @@ noop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
* you would be well advised to improve this code. * you would be well advised to improve this code.
*/ */
METHODDEF void METHODDEF(void)
int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
{ {
@@ -229,7 +231,7 @@ int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
* It's still a box filter. * It's still a box filter.
*/ */
METHODDEF void METHODDEF(void)
h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
{ {
@@ -257,7 +259,7 @@ h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
* It's still a box filter. * It's still a box filter.
*/ */
METHODDEF void METHODDEF(void)
h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
{ {
@@ -300,7 +302,7 @@ h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
* alternate pixel locations (a simple ordered dither pattern). * alternate pixel locations (a simple ordered dither pattern).
*/ */
METHODDEF void METHODDEF(void)
h2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, h2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
{ {
@@ -341,7 +343,7 @@ h2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
* context from the main buffer controller (see initialization code). * context from the main buffer controller (see initialization code).
*/ */
METHODDEF void METHODDEF(void)
h2v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, h2v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
{ {
@@ -395,7 +397,7 @@ h2v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
* Module initialization routine for upsampling. * Module initialization routine for upsampling.
*/ */
GLOBAL void GLOBAL(void)
jinit_upsampler (j_decompress_ptr cinfo) jinit_upsampler (j_decompress_ptr cinfo)
{ {
my_upsample_ptr upsample; my_upsample_ptr upsample;
@@ -447,18 +449,32 @@ jinit_upsampler (j_decompress_ptr cinfo)
} else if (h_in_group * 2 == h_out_group && } else if (h_in_group * 2 == h_out_group &&
v_in_group == v_out_group) { v_in_group == v_out_group) {
/* Special cases for 2h1v upsampling */ /* Special cases for 2h1v upsampling */
if (do_fancy && compptr->downsampled_width > 2) if (do_fancy && compptr->downsampled_width > 2) {
upsample->methods[ci] = h2v1_fancy_upsample; if (jsimd_can_h2v1_fancy_upsample())
else upsample->methods[ci] = jsimd_h2v1_fancy_upsample;
upsample->methods[ci] = h2v1_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 && } else if (h_in_group * 2 == h_out_group &&
v_in_group * 2 == v_out_group) { v_in_group * 2 == v_out_group) {
/* Special cases for 2h2v upsampling */ /* Special cases for 2h2v upsampling */
if (do_fancy && compptr->downsampled_width > 2) { 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; upsample->pub.need_context_rows = TRUE;
} else } else {
upsample->methods[ci] = h2v2_upsample; 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 && } else if ((h_out_group % h_in_group) == 0 &&
(v_out_group % v_in_group) == 0) { (v_out_group % v_in_group) == 0) {
/* Generic integral-factors upsampling method */ /* Generic integral-factors upsampling method */

View File

@@ -1,7 +1,7 @@
/* /*
* jdtrans.c * jdtrans.c
* *
* Copyright (C) 1995, Thomas G. Lane. * Copyright (C) 1995-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -16,7 +16,7 @@
/* Forward declarations */ /* Forward declarations */
LOCAL void transdecode_master_selection JPP((j_decompress_ptr cinfo)); LOCAL(void) transdecode_master_selection JPP((j_decompress_ptr cinfo));
/* /*
@@ -30,43 +30,61 @@ LOCAL void transdecode_master_selection JPP((j_decompress_ptr cinfo));
* To release the memory occupied by the virtual arrays, call * To release the memory occupied by the virtual arrays, call
* jpeg_finish_decompress() when done with the data. * 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 * Returns NULL if suspended. This case need be checked only if
* a suspending data source is used. * a suspending data source is used.
*/ */
GLOBAL jvirt_barray_ptr * GLOBAL(jvirt_barray_ptr *)
jpeg_read_coefficients (j_decompress_ptr cinfo) jpeg_read_coefficients (j_decompress_ptr cinfo)
{ {
if (cinfo->global_state == DSTATE_READY) { if (cinfo->global_state == DSTATE_READY) {
/* First call: initialize active modules */ /* First call: initialize active modules */
transdecode_master_selection(cinfo); transdecode_master_selection(cinfo);
cinfo->global_state = DSTATE_RDCOEFS; cinfo->global_state = DSTATE_RDCOEFS;
} else if (cinfo->global_state != DSTATE_RDCOEFS) }
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); if (cinfo->global_state == DSTATE_RDCOEFS) {
/* Absorb whole file into the coef buffer */ /* Absorb whole file into the coef buffer */
for (;;) { for (;;) {
int retcode; int retcode;
/* Call progress monitor hook if present */ /* Call progress monitor hook if present */
if (cinfo->progress != NULL) if (cinfo->progress != NULL)
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
/* Absorb some more input */ /* Absorb some more input */
retcode = (*cinfo->inputctl->consume_input) (cinfo); retcode = (*cinfo->inputctl->consume_input) (cinfo);
if (retcode == JPEG_SUSPENDED) if (retcode == JPEG_SUSPENDED)
return NULL; return NULL;
if (retcode == JPEG_REACHED_EOI) if (retcode == JPEG_REACHED_EOI)
break; break;
/* Advance progress counter if appropriate */ /* Advance progress counter if appropriate */
if (cinfo->progress != NULL && if (cinfo->progress != NULL &&
(retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) { (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) {
if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) { if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) {
/* startup underestimated number of scans; ratchet up one scan */ /* startup underestimated number of scans; ratchet up one scan */
cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows; 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 */ /* At this point we should be in state DSTATE_STOPPING if being used
cinfo->global_state = DSTATE_STOPPING; * standalone, or in state DSTATE_BUFIMAGE if being invoked to get access
return cinfo->coef->coef_arrays; * 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 */
} }
@@ -75,9 +93,12 @@ jpeg_read_coefficients (j_decompress_ptr cinfo)
* This substitutes for jdmaster.c's initialization of the full decompressor. * This substitutes for jdmaster.c's initialization of the full decompressor.
*/ */
LOCAL void LOCAL(void)
transdecode_master_selection (j_decompress_ptr cinfo) 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. */ /* Entropy decoding: either Huffman or arithmetic coding. */
if (cinfo->arith_code) { if (cinfo->arith_code) {
ERREXIT(cinfo, JERR_ARITH_NOTIMPL); ERREXIT(cinfo, JERR_ARITH_NOTIMPL);

View File

@@ -1,7 +1,7 @@
/* /*
* jerror.c * jerror.c
* *
* Copyright (C) 1991-1994, Thomas G. Lane. * Copyright (C) 1991-1998, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * 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 * stderr is the right thing to do. Many applications will want to replace
* some or all of these routines. * 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. * These routines are used by both the compression and decompression code.
*/ */
@@ -19,6 +24,10 @@
#include "jversion.h" #include "jversion.h"
#include "jerror.h" #include "jerror.h"
#ifdef USE_WINDOWS_MESSAGEBOX
#include <windows.h>
#endif
#ifndef EXIT_FAILURE /* define exit() codes if not provided */ #ifndef EXIT_FAILURE /* define exit() codes if not provided */
#define EXIT_FAILURE 1 #define EXIT_FAILURE 1
#endif #endif
@@ -57,7 +66,7 @@ const char * const jpeg_std_message_table[] = {
* or jpeg_destroy) at some point. * or jpeg_destroy) at some point.
*/ */
METHODDEF void METHODDEF(void)
error_exit (j_common_ptr cinfo) error_exit (j_common_ptr cinfo)
{ {
/* Always display the message */ /* Always display the message */
@@ -74,9 +83,18 @@ error_exit (j_common_ptr cinfo)
* Actual output of an error or trace message. * Actual output of an error or trace message.
* Applications may override this method to send JPEG messages somewhere * Applications may override this method to send JPEG messages somewhere
* other than stderr. * 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 METHODDEF(void)
output_message (j_common_ptr cinfo) output_message (j_common_ptr cinfo)
{ {
char buffer[JMSG_LENGTH_MAX]; char buffer[JMSG_LENGTH_MAX];
@@ -84,8 +102,14 @@ output_message (j_common_ptr cinfo)
/* Create the message */ /* Create the message */
(*cinfo->err->format_message) (cinfo, buffer); (*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 */ /* Send it to stderr, adding a newline */
fprintf(stderr, "%s\n", buffer); fprintf(stderr, "%s\n", buffer);
#endif
} }
@@ -100,7 +124,7 @@ output_message (j_common_ptr cinfo)
* or change the policy about which messages to display. * or change the policy about which messages to display.
*/ */
METHODDEF void METHODDEF(void)
emit_message (j_common_ptr cinfo, int msg_level) emit_message (j_common_ptr cinfo, int msg_level)
{ {
struct jpeg_error_mgr * err = cinfo->err; struct jpeg_error_mgr * err = cinfo->err;
@@ -129,7 +153,7 @@ emit_message (j_common_ptr cinfo, int msg_level)
* Few applications should need to override this method. * Few applications should need to override this method.
*/ */
METHODDEF void METHODDEF(void)
format_message (j_common_ptr cinfo, char * buffer) format_message (j_common_ptr cinfo, char * buffer)
{ {
struct jpeg_error_mgr * err = cinfo->err; struct jpeg_error_mgr * err = cinfo->err;
@@ -184,7 +208,7 @@ format_message (j_common_ptr cinfo, char * buffer)
* this method if it has additional error processing state. * this method if it has additional error processing state.
*/ */
METHODDEF void METHODDEF(void)
reset_error_mgr (j_common_ptr cinfo) reset_error_mgr (j_common_ptr cinfo)
{ {
cinfo->err->num_warnings = 0; cinfo->err->num_warnings = 0;
@@ -203,7 +227,7 @@ reset_error_mgr (j_common_ptr cinfo)
* after which the application may override some of the methods. * after which the application may override some of the methods.
*/ */
GLOBAL struct jpeg_error_mgr * GLOBAL(struct jpeg_error_mgr *)
jpeg_std_error (struct jpeg_error_mgr * err) jpeg_std_error (struct jpeg_error_mgr * err)
{ {
err->error_exit = error_exit; err->error_exit = error_exit;

View File

@@ -1,7 +1,7 @@
/* /*
* jerror.h * jerror.h
* *
* Copyright (C) 1994-1995, Thomas G. Lane. * Copyright (C) 1994-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -45,10 +45,14 @@ 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_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix")
JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode") JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode")
JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS") JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS")
JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range")
JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported") 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_IN_COLORSPACE, "Bogus input colorspace")
JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace") JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace")
JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length") JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length")
JMESSAGE(JERR_BAD_LIB_VERSION,
"Wrong JPEG library version: library is %d, caller expects %d")
JMESSAGE(JERR_BAD_MCU_SIZE, "Sampling factors too large for interleaved scan") JMESSAGE(JERR_BAD_MCU_SIZE, "Sampling factors too large for interleaved scan")
JMESSAGE(JERR_BAD_POOL_ID, "Invalid memory pool code %d") JMESSAGE(JERR_BAD_POOL_ID, "Invalid memory pool code %d")
JMESSAGE(JERR_BAD_PRECISION, "Unsupported JPEG data precision %d") JMESSAGE(JERR_BAD_PRECISION, "Unsupported JPEG data precision %d")
@@ -59,6 +63,8 @@ JMESSAGE(JERR_BAD_PROG_SCRIPT,
JMESSAGE(JERR_BAD_SAMPLING, "Bogus sampling factors") JMESSAGE(JERR_BAD_SAMPLING, "Bogus sampling factors")
JMESSAGE(JERR_BAD_SCAN_SCRIPT, "Invalid scan script at entry %d") JMESSAGE(JERR_BAD_SCAN_SCRIPT, "Invalid scan script at entry %d")
JMESSAGE(JERR_BAD_STATE, "Improper call to JPEG library in state %d") JMESSAGE(JERR_BAD_STATE, "Improper call to JPEG library in state %d")
JMESSAGE(JERR_BAD_STRUCT_SIZE,
"JPEG parameter struct mismatch: library thinks size is %u, caller expects %u")
JMESSAGE(JERR_BAD_VIRTUAL_ACCESS, "Bogus virtual array access") JMESSAGE(JERR_BAD_VIRTUAL_ACCESS, "Bogus virtual array access")
JMESSAGE(JERR_BUFFER_SIZE, "Buffer passed to JPEG library is too small") JMESSAGE(JERR_BUFFER_SIZE, "Buffer passed to JPEG library is too small")
JMESSAGE(JERR_CANT_SUSPEND, "Suspension not allowed here") JMESSAGE(JERR_CANT_SUSPEND, "Suspension not allowed here")
@@ -67,7 +73,6 @@ JMESSAGE(JERR_COMPONENT_COUNT, "Too many color components: %d, max %d")
JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request") JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request")
JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d") JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d")
JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x") 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_DHT_INDEX, "Bogus DHT index %d")
JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d") JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d")
JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)") JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)")
@@ -130,12 +135,13 @@ JMESSAGE(JTRC_EMS_CLOSE, "Freed EMS handle %u")
JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u") JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u")
JMESSAGE(JTRC_EOI, "End Of Image") JMESSAGE(JTRC_EOI, "End Of Image")
JMESSAGE(JTRC_HUFFBITS, " %3d %3d %3d %3d %3d %3d %3d %3d") 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, JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE,
"Warning: thumbnail image size does not match data length %u") "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_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_PARMLESS_MARKER, "Unexpected marker 0x%02x")
JMESSAGE(JTRC_QUANTVALS, " %4u %4u %4u %4u %4u %4u %4u %4u") JMESSAGE(JTRC_QUANTVALS, " %4u %4u %4u %4u %4u %4u %4u %4u")
JMESSAGE(JTRC_QUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors") JMESSAGE(JTRC_QUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors")
@@ -153,6 +159,12 @@ JMESSAGE(JTRC_SOS_COMPONENT, " Component %d: dc=%d ac=%d")
JMESSAGE(JTRC_SOS_PARAMS, " Ss=%d, Se=%d, Ah=%d, Al=%d") JMESSAGE(JTRC_SOS_PARAMS, " Ss=%d, Se=%d, Ah=%d, Al=%d")
JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s") JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s")
JMESSAGE(JTRC_TFILE_OPEN, "Opened 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, JMESSAGE(JTRC_UNKNOWN_IDS,
"Unrecognized component IDs %d %d %d, assuming YCbCr") "Unrecognized component IDs %d %d %d, assuming YCbCr")
JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u") JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u")
@@ -259,6 +271,12 @@ JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines")
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
(cinfo)->err->msg_code = (code); \ (cinfo)->err->msg_code = (code); \
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) (*(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) \ #define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8) \
MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \

View File

@@ -1,7 +1,7 @@
/* /*
* jfdctflt.c * jfdctflt.c
* *
* Copyright (C) 1994, Thomas G. Lane. * Copyright (C) 1994-1996, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -55,7 +55,7 @@
* Perform the forward DCT on one block of samples. * Perform the forward DCT on one block of samples.
*/ */
GLOBAL void GLOBAL(void)
jpeg_fdct_float (FAST_FLOAT * data) jpeg_fdct_float (FAST_FLOAT * data)
{ {
FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;

View File

@@ -1,7 +1,7 @@
/* /*
* jfdctfst.c * jfdctfst.c
* *
* Copyright (C) 1994, Thomas G. Lane. * Copyright (C) 1994-1996, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -110,7 +110,7 @@
* Perform the forward DCT on one block of samples. * Perform the forward DCT on one block of samples.
*/ */
GLOBAL void GLOBAL(void)
jpeg_fdct_ifast (DCTELEM * data) jpeg_fdct_ifast (DCTELEM * data)
{ {
DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;

View File

@@ -1,7 +1,7 @@
/* /*
* jfdctint.c * jfdctint.c
* *
* Copyright (C) 1991-1994, Thomas G. Lane. * Copyright (C) 1991-1996, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -136,7 +136,7 @@
* Perform the forward DCT on one block of samples. * Perform the forward DCT on one block of samples.
*/ */
GLOBAL void GLOBAL(void)
jpeg_fdct_islow (DCTELEM * data) jpeg_fdct_islow (DCTELEM * data)
{ {
INT32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; INT32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;

View File

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

View File

@@ -1,7 +1,7 @@
/* /*
* jidctfst.c * jidctfst.c
* *
* Copyright (C) 1994-1995, Thomas G. Lane. * Copyright (C) 1994-1998, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -164,7 +164,7 @@
* Perform dequantization and inverse DCT on one block of coefficients. * Perform dequantization and inverse DCT on one block of coefficients.
*/ */
GLOBAL void GLOBAL(void)
jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr, jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JCOEFPTR coef_block,
JSAMPARRAY output_buf, JDIMENSION output_col) JSAMPARRAY output_buf, JDIMENSION output_col)
@@ -197,9 +197,10 @@ jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr,
* column DCT calculations can be simplified this way. * column DCT calculations can be simplified this way.
*/ */
if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*2] | inptr[DCTSIZE*3] | if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
inptr[DCTSIZE*4] | inptr[DCTSIZE*5] | inptr[DCTSIZE*6] | inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
inptr[DCTSIZE*7]) == 0) { inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
inptr[DCTSIZE*7] == 0) {
/* AC terms all zero */ /* AC terms all zero */
int dcval = (int) DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); 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 #ifndef NO_ZERO_ROW_TEST
if ((wsptr[1] | wsptr[2] | wsptr[3] | wsptr[4] | wsptr[5] | wsptr[6] | if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 &&
wsptr[7]) == 0) { wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
/* AC terms all zero */ /* AC terms all zero */
JSAMPLE dcval = range_limit[IDESCALE(wsptr[0], PASS1_BITS+3) JSAMPLE dcval = range_limit[IDESCALE(wsptr[0], PASS1_BITS+3)
& RANGE_MASK]; & RANGE_MASK];

View File

@@ -1,7 +1,7 @@
/* /*
* jidctint.c * jidctint.c
* *
* Copyright (C) 1991-1994, Thomas G. Lane. * Copyright (C) 1991-1998, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -144,7 +144,7 @@
* Perform dequantization and inverse DCT on one block of coefficients. * Perform dequantization and inverse DCT on one block of coefficients.
*/ */
GLOBAL void GLOBAL(void)
jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr, jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JCOEFPTR coef_block,
JSAMPARRAY output_buf, JDIMENSION output_col) JSAMPARRAY output_buf, JDIMENSION output_col)
@@ -178,9 +178,10 @@ jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr,
* column DCT calculations can be simplified this way. * column DCT calculations can be simplified this way.
*/ */
if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*2] | inptr[DCTSIZE*3] | if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
inptr[DCTSIZE*4] | inptr[DCTSIZE*5] | inptr[DCTSIZE*6] | inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
inptr[DCTSIZE*7]) == 0) { inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
inptr[DCTSIZE*7] == 0) {
/* AC terms all zero */ /* AC terms all zero */
int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS; 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 #ifndef NO_ZERO_ROW_TEST
if ((wsptr[1] | wsptr[2] | wsptr[3] | wsptr[4] | wsptr[5] | wsptr[6] | if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 &&
wsptr[7]) == 0) { wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
/* AC terms all zero */ /* AC terms all zero */
JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3) JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
& RANGE_MASK]; & RANGE_MASK];

View File

@@ -1,7 +1,7 @@
/* /*
* jidctred.c * jidctred.c
* *
* Copyright (C) 1994, Thomas G. Lane. * Copyright (C) 1994-1998, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -114,7 +114,7 @@
* producing a reduced-size 4x4 output block. * producing a reduced-size 4x4 output block.
*/ */
GLOBAL void GLOBAL(void)
jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr, jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JCOEFPTR coef_block,
JSAMPARRAY output_buf, JDIMENSION output_col) JSAMPARRAY output_buf, JDIMENSION output_col)
@@ -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 */ /* Don't bother to process column 4, because second pass won't use it */
if (ctr == DCTSIZE-4) if (ctr == DCTSIZE-4)
continue; continue;
if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*2] | inptr[DCTSIZE*3] | if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
inptr[DCTSIZE*5] | inptr[DCTSIZE*6] | inptr[DCTSIZE*7]) == 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 */ /* AC terms all zero; we need not examine term 4 for 4x4 output */
int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS; 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 ... */ /* It's not clear whether a zero row test is worthwhile here ... */
#ifndef NO_ZERO_ROW_TEST #ifndef NO_ZERO_ROW_TEST
if ((wsptr[1] | wsptr[2] | wsptr[3] | wsptr[5] | wsptr[6] | if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 &&
wsptr[7]) == 0) { wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
/* AC terms all zero */ /* AC terms all zero */
JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3) JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
& RANGE_MASK]; & RANGE_MASK];
@@ -266,7 +267,7 @@ jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
* producing a reduced-size 2x2 output block. * producing a reduced-size 2x2 output block.
*/ */
GLOBAL void GLOBAL(void)
jpeg_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr, jpeg_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JCOEFPTR coef_block,
JSAMPARRAY output_buf, JDIMENSION output_col) JSAMPARRAY output_buf, JDIMENSION output_col)
@@ -290,8 +291,8 @@ jpeg_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
/* Don't bother to process columns 2,4,6 */ /* Don't bother to process columns 2,4,6 */
if (ctr == DCTSIZE-2 || ctr == DCTSIZE-4 || ctr == DCTSIZE-6) if (ctr == DCTSIZE-2 || ctr == DCTSIZE-4 || ctr == DCTSIZE-6)
continue; continue;
if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*3] | if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*3] == 0 &&
inptr[DCTSIZE*5] | inptr[DCTSIZE*7]) == 0) { inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*7] == 0) {
/* AC terms all zero; we need not examine terms 2,4,6 for 2x2 output */ /* 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; 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 ... */ /* It's not clear whether a zero row test is worthwhile here ... */
#ifndef NO_ZERO_ROW_TEST #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 */ /* AC terms all zero */
JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3) JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
& RANGE_MASK]; & RANGE_MASK];
@@ -374,7 +375,7 @@ jpeg_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
* producing a reduced-size 1x1 output block. * producing a reduced-size 1x1 output block.
*/ */
GLOBAL void GLOBAL(void)
jpeg_idct_1x1 (j_decompress_ptr cinfo, jpeg_component_info * compptr, jpeg_idct_1x1 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JCOEFPTR coef_block,
JSAMPARRAY output_buf, JDIMENSION output_col) JSAMPARRAY output_buf, JDIMENSION output_col)

View File

@@ -1,167 +0,0 @@
/*
* jmemansi.c
*
* Copyright (C) 1992-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 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-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 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 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

205
jmemmgr.c
View File

@@ -1,7 +1,7 @@
/* /*
* jmemmgr.c * jmemmgr.c
* *
* Copyright (C) 1991-1995, Thomas G. Lane. * Copyright (C) 1991-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * 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. * requirement, and we had better do so too.
* There isn't any really portable way to determine the worst-case alignment * There isn't any really portable way to determine the worst-case alignment
* requirement. This module assumes that the alignment requirement is * requirement. This module assumes that the alignment requirement is
* multiples of sizeof(ALIGN_TYPE). * multiples of ALIGN_SIZE.
* By default, we define ALIGN_TYPE as double. This is necessary on some * 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 * workstations (where doubles really do need 8-byte alignment) and will work
* fine on nearly everything. If your machine has lesser alignment needs, * 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 * 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. * 680x0 compilers that define double as a 10-byte IEEE extended float.
* Doing 10-byte alignment is counterproductive because longwords won't be * 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. * such a compiler.
*/ */
#ifndef ALIGN_TYPE /* so can override from jconfig.h */ #ifndef ALIGN_SIZE /* so can override from jconfig.h */
#define ALIGN_TYPE double #ifndef WITH_SIMD
#define ALIGN_SIZE SIZEOF(double)
#else
#define ALIGN_SIZE 16 /* Most SIMD implementations require this */
#endif
#endif #endif
/* /*
* We allocate objects from "pools", where each pool is gotten with a single * 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. * header with a link to the next pool of the same class.
* Small and large pool headers are identical except that the latter's * Small and large pool headers are identical except that the latter's
* link pointer must be FAR on 80x86 machines. * 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 { typedef struct small_pool_struct {
struct { small_pool_ptr next; /* next in list of pools */
small_pool_ptr next; /* next in list of pools */ size_t bytes_used; /* how many bytes already used within pool */
size_t bytes_used; /* how many bytes already used within pool */ size_t bytes_left; /* bytes still available in this pool */
size_t bytes_left; /* bytes still available in this pool */
} hdr;
ALIGN_TYPE dummy; /* included in union to ensure alignment */
} small_pool_hdr; } 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 { typedef struct large_pool_struct {
struct { large_pool_ptr next; /* next in list of pools */
large_pool_ptr next; /* next in list of pools */ size_t bytes_used; /* how many bytes already used within pool */
size_t bytes_used; /* how many bytes already used within pool */ size_t bytes_left; /* bytes still available in this pool */
size_t bytes_left; /* bytes still available in this pool */
} hdr;
ALIGN_TYPE dummy; /* included in union to ensure alignment */
} large_pool_hdr; } large_pool_hdr;
/* /*
* Here is the full definition of a memory manager object. * Here is the full definition of a memory manager object.
*/ */
@@ -182,7 +175,7 @@ struct jvirt_barray_control {
#ifdef MEM_STATS /* optional extra stuff for statistics */ #ifdef MEM_STATS /* optional extra stuff for statistics */
LOCAL void LOCAL(void)
print_mem_stats (j_common_ptr cinfo, int pool_id) print_mem_stats (j_common_ptr cinfo, int pool_id)
{ {
my_mem_ptr mem = (my_mem_ptr) cinfo->mem; my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
@@ -197,23 +190,23 @@ print_mem_stats (j_common_ptr cinfo, int pool_id)
pool_id, mem->total_space_allocated); pool_id, mem->total_space_allocated);
for (lhdr_ptr = mem->large_list[pool_id]; lhdr_ptr != NULL; 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", 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; 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", fprintf(stderr, " Small chunk used %ld free %ld\n",
(long) shdr_ptr->hdr.bytes_used, (long) shdr_ptr->bytes_used,
(long) shdr_ptr->hdr.bytes_left); (long) shdr_ptr->bytes_left);
} }
} }
#endif /* MEM_STATS */ #endif /* MEM_STATS */
LOCAL void LOCAL(void)
out_of_memory (j_common_ptr cinfo, int which) out_of_memory (j_common_ptr cinfo, int which)
/* Report an out-of-memory error and stop execution */ /* Report an out-of-memory error and stop execution */
/* If we compiled MEM_STATS support, report alloc requests before dying */ /* If we compiled MEM_STATS support, report alloc requests before dying */
@@ -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. * 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 * 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. * 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] = static const size_t first_pool_slop[JPOOL_NUMPOOLS] =
@@ -253,40 +250,43 @@ static const size_t extra_pool_slop[JPOOL_NUMPOOLS] =
#define MIN_SLOP 50 /* greater than 0 to avoid futile looping */ #define MIN_SLOP 50 /* greater than 0 to avoid futile looping */
METHODDEF void * METHODDEF(void *)
alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject) alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
/* Allocate a "small" object */ /* Allocate a "small" object */
{ {
my_mem_ptr mem = (my_mem_ptr) cinfo->mem; my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
small_pool_ptr hdr_ptr, prev_hdr_ptr; small_pool_ptr hdr_ptr, prev_hdr_ptr;
char * data_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) */ /* 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 */ 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 */ /* See if space is available in any existing pool */
if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS) if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
prev_hdr_ptr = NULL; prev_hdr_ptr = NULL;
hdr_ptr = mem->small_list[pool_id]; hdr_ptr = mem->small_list[pool_id];
while (hdr_ptr != NULL) { while (hdr_ptr != NULL) {
if (hdr_ptr->hdr.bytes_left >= sizeofobject) if (hdr_ptr->bytes_left >= sizeofobject)
break; /* found pool with enough space */ break; /* found pool with enough space */
prev_hdr_ptr = hdr_ptr; prev_hdr_ptr = hdr_ptr;
hdr_ptr = hdr_ptr->hdr.next; hdr_ptr = hdr_ptr->next;
} }
/* Time to make a new pool? */ /* Time to make a new pool? */
if (hdr_ptr == NULL) { if (hdr_ptr == NULL) {
/* min_request is what we need now, slop is what will be leftover */ /* 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? */ if (prev_hdr_ptr == NULL) /* first pool in class? */
slop = first_pool_slop[pool_id]; slop = first_pool_slop[pool_id];
else else
@@ -305,20 +305,23 @@ alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
} }
mem->total_space_allocated += min_request + slop; mem->total_space_allocated += min_request + slop;
/* Success, initialize the new pool header and add to end of list */ /* Success, initialize the new pool header and add to end of list */
hdr_ptr->hdr.next = NULL; hdr_ptr->next = NULL;
hdr_ptr->hdr.bytes_used = 0; hdr_ptr->bytes_used = 0;
hdr_ptr->hdr.bytes_left = sizeofobject + slop; hdr_ptr->bytes_left = sizeofobject + slop;
if (prev_hdr_ptr == NULL) /* first pool in class? */ if (prev_hdr_ptr == NULL) /* first pool in class? */
mem->small_list[pool_id] = hdr_ptr; mem->small_list[pool_id] = hdr_ptr;
else else
prev_hdr_ptr->hdr.next = hdr_ptr; prev_hdr_ptr->next = hdr_ptr;
} }
/* OK, allocate the object from the current pool */ /* OK, allocate the object from the current pool */
data_ptr = (char *) (hdr_ptr + 1); /* point to first data byte in pool */ data_ptr = (char *) hdr_ptr; /* point to first data byte in pool... */
data_ptr += hdr_ptr->hdr.bytes_used; /* point to place for object */ data_ptr += SIZEOF(small_pool_hdr); /* ...by skipping the header... */
hdr_ptr->hdr.bytes_used += sizeofobject; if ((unsigned long)data_ptr % ALIGN_SIZE) /* ...and adjust for alignment */
hdr_ptr->hdr.bytes_left -= sizeofobject; data_ptr += ALIGN_SIZE - (unsigned long)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; return (void *) data_ptr;
} }
@@ -338,43 +341,51 @@ alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
* deliberately bunch rows together to ensure a large request size. * deliberately bunch rows together to ensure a large request size.
*/ */
METHODDEF void FAR * METHODDEF(void FAR *)
alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject) alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
/* Allocate a "large" object */ /* Allocate a "large" object */
{ {
my_mem_ptr mem = (my_mem_ptr) cinfo->mem; my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
large_pool_ptr hdr_ptr; 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) */ /* 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 */ 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 */ /* Always make a new pool */
if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS) if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
hdr_ptr = (large_pool_ptr) jpeg_get_large(cinfo, sizeofobject + 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) if (hdr_ptr == NULL)
out_of_memory(cinfo, 4); /* jpeg_get_large failed */ 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 */ /* 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, /* We maintain space counts in each pool header for statistical purposes,
* even though they are not needed for allocation. * even though they are not needed for allocation.
*/ */
hdr_ptr->hdr.bytes_used = sizeofobject; hdr_ptr->bytes_used = sizeofobject;
hdr_ptr->hdr.bytes_left = 0; hdr_ptr->bytes_left = 0;
mem->large_list[pool_id] = hdr_ptr; 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 ((unsigned long)data_ptr % ALIGN_SIZE) /* ...and adjust for alignment */
data_ptr += ALIGN_SIZE - (unsigned long)data_ptr % ALIGN_SIZE;
return (void FAR *) data_ptr;
} }
@@ -389,9 +400,13 @@ 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 * 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 * object so that it can be saved away if this sarray is the workspace for
* a virtual array. * 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 METHODDEF(JSAMPARRAY)
alloc_sarray (j_common_ptr cinfo, int pool_id, alloc_sarray (j_common_ptr cinfo, int pool_id,
JDIMENSION samplesperrow, JDIMENSION numrows) JDIMENSION samplesperrow, JDIMENSION numrows)
/* Allocate a 2-D sample array */ /* Allocate a 2-D sample array */
@@ -402,6 +417,11 @@ alloc_sarray (j_common_ptr cinfo, int pool_id,
JDIMENSION rowsperchunk, currow, i; JDIMENSION rowsperchunk, currow, i;
long ltemp; long ltemp;
/* Make sure each row is properly aligned */
if ((ALIGN_SIZE % SIZEOF(JSAMPLE)) != 0)
out_of_memory(cinfo, 5); /* safety check */
samplesperrow = jround_up(samplesperrow, (2 * ALIGN_SIZE) / SIZEOF(JSAMPLE));
/* Calculate max # of rows allowed in one allocation chunk */ /* Calculate max # of rows allowed in one allocation chunk */
ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) / ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
((long) samplesperrow * SIZEOF(JSAMPLE)); ((long) samplesperrow * SIZEOF(JSAMPLE));
@@ -439,7 +459,7 @@ alloc_sarray (j_common_ptr cinfo, int pool_id,
* This is essentially the same as the code for sample arrays, above. * This is essentially the same as the code for sample arrays, above.
*/ */
METHODDEF JBLOCKARRAY METHODDEF(JBLOCKARRAY)
alloc_barray (j_common_ptr cinfo, int pool_id, alloc_barray (j_common_ptr cinfo, int pool_id,
JDIMENSION blocksperrow, JDIMENSION numrows) JDIMENSION blocksperrow, JDIMENSION numrows)
/* Allocate a 2-D coefficient-block array */ /* Allocate a 2-D coefficient-block array */
@@ -450,6 +470,10 @@ alloc_barray (j_common_ptr cinfo, int pool_id,
JDIMENSION rowsperchunk, currow, i; JDIMENSION rowsperchunk, currow, i;
long ltemp; 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 */ /* Calculate max # of rows allowed in one allocation chunk */
ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) / ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
((long) blocksperrow * SIZEOF(JBLOCK)); ((long) blocksperrow * SIZEOF(JBLOCK));
@@ -519,7 +543,7 @@ alloc_barray (j_common_ptr cinfo, int pool_id,
*/ */
METHODDEF jvirt_sarray_ptr METHODDEF(jvirt_sarray_ptr)
request_virt_sarray (j_common_ptr cinfo, int pool_id, boolean pre_zero, request_virt_sarray (j_common_ptr cinfo, int pool_id, boolean pre_zero,
JDIMENSION samplesperrow, JDIMENSION numrows, JDIMENSION samplesperrow, JDIMENSION numrows,
JDIMENSION maxaccess) JDIMENSION maxaccess)
@@ -549,7 +573,7 @@ request_virt_sarray (j_common_ptr cinfo, int pool_id, boolean pre_zero,
} }
METHODDEF jvirt_barray_ptr METHODDEF(jvirt_barray_ptr)
request_virt_barray (j_common_ptr cinfo, int pool_id, boolean pre_zero, request_virt_barray (j_common_ptr cinfo, int pool_id, boolean pre_zero,
JDIMENSION blocksperrow, JDIMENSION numrows, JDIMENSION blocksperrow, JDIMENSION numrows,
JDIMENSION maxaccess) JDIMENSION maxaccess)
@@ -579,7 +603,7 @@ request_virt_barray (j_common_ptr cinfo, int pool_id, boolean pre_zero,
} }
METHODDEF void METHODDEF(void)
realize_virt_arrays (j_common_ptr cinfo) realize_virt_arrays (j_common_ptr cinfo)
/* Allocate the in-memory buffers for any unrealized virtual arrays */ /* Allocate the in-memory buffers for any unrealized virtual arrays */
{ {
@@ -686,7 +710,7 @@ realize_virt_arrays (j_common_ptr cinfo)
} }
LOCAL void LOCAL(void)
do_sarray_io (j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing) do_sarray_io (j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing)
/* Do backing store read or write of a virtual sample array */ /* Do backing store read or write of a virtual sample array */
{ {
@@ -719,7 +743,7 @@ do_sarray_io (j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing)
} }
LOCAL void LOCAL(void)
do_barray_io (j_common_ptr cinfo, jvirt_barray_ptr ptr, boolean writing) do_barray_io (j_common_ptr cinfo, jvirt_barray_ptr ptr, boolean writing)
/* Do backing store read or write of a virtual coefficient-block array */ /* Do backing store read or write of a virtual coefficient-block array */
{ {
@@ -752,7 +776,7 @@ do_barray_io (j_common_ptr cinfo, jvirt_barray_ptr ptr, boolean writing)
} }
METHODDEF JSAMPARRAY METHODDEF(JSAMPARRAY)
access_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr, access_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr,
JDIMENSION start_row, JDIMENSION num_rows, JDIMENSION start_row, JDIMENSION num_rows,
boolean writable) boolean writable)
@@ -837,7 +861,7 @@ access_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr,
} }
METHODDEF JBLOCKARRAY METHODDEF(JBLOCKARRAY)
access_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr, access_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr,
JDIMENSION start_row, JDIMENSION num_rows, JDIMENSION start_row, JDIMENSION num_rows,
boolean writable) boolean writable)
@@ -926,7 +950,7 @@ access_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr,
* Release all objects belonging to a specified pool. * Release all objects belonging to a specified pool.
*/ */
METHODDEF void METHODDEF(void)
free_pool (j_common_ptr cinfo, int pool_id) free_pool (j_common_ptr cinfo, int pool_id)
{ {
my_mem_ptr mem = (my_mem_ptr) cinfo->mem; my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
@@ -968,9 +992,9 @@ free_pool (j_common_ptr cinfo, int pool_id)
mem->large_list[pool_id] = NULL; mem->large_list[pool_id] = NULL;
while (lhdr_ptr != NULL) { while (lhdr_ptr != NULL) {
large_pool_ptr next_lhdr_ptr = lhdr_ptr->hdr.next; large_pool_ptr next_lhdr_ptr = lhdr_ptr->next;
space_freed = lhdr_ptr->hdr.bytes_used + space_freed = lhdr_ptr->bytes_used +
lhdr_ptr->hdr.bytes_left + lhdr_ptr->bytes_left +
SIZEOF(large_pool_hdr); SIZEOF(large_pool_hdr);
jpeg_free_large(cinfo, (void FAR *) lhdr_ptr, space_freed); jpeg_free_large(cinfo, (void FAR *) lhdr_ptr, space_freed);
mem->total_space_allocated -= 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; mem->small_list[pool_id] = NULL;
while (shdr_ptr != NULL) { while (shdr_ptr != NULL) {
small_pool_ptr next_shdr_ptr = shdr_ptr->hdr.next; small_pool_ptr next_shdr_ptr = shdr_ptr->next;
space_freed = shdr_ptr->hdr.bytes_used + space_freed = shdr_ptr->bytes_used +
shdr_ptr->hdr.bytes_left + shdr_ptr->bytes_left +
SIZEOF(small_pool_hdr); SIZEOF(small_pool_hdr);
jpeg_free_small(cinfo, (void *) shdr_ptr, space_freed); jpeg_free_small(cinfo, (void *) shdr_ptr, space_freed);
mem->total_space_allocated -= space_freed; mem->total_space_allocated -= space_freed;
@@ -998,7 +1022,7 @@ free_pool (j_common_ptr cinfo, int pool_id)
* Note that this cannot be called unless cinfo->mem is non-NULL. * Note that this cannot be called unless cinfo->mem is non-NULL.
*/ */
METHODDEF void METHODDEF(void)
self_destruct (j_common_ptr cinfo) self_destruct (j_common_ptr cinfo)
{ {
int pool; int pool;
@@ -1024,7 +1048,7 @@ self_destruct (j_common_ptr cinfo)
* When this is called, only the error manager pointer is valid in cinfo! * When this is called, only the error manager pointer is valid in cinfo!
*/ */
GLOBAL void GLOBAL(void)
jinit_memory_mgr (j_common_ptr cinfo) jinit_memory_mgr (j_common_ptr cinfo)
{ {
my_mem_ptr mem; my_mem_ptr mem;
@@ -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. * 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. * 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); ERREXIT(cinfo, JERR_BAD_ALIGN_TYPE);
/* MAX_ALLOC_CHUNK must be representable as type size_t, and must be /* 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. * Again, an "unreachable code" warning may be ignored here.
* But a "constant too large" warning means you need to fix MAX_ALLOC_CHUNK. * But a "constant too large" warning means you need to fix MAX_ALLOC_CHUNK.
*/ */
test_mac = (size_t) MAX_ALLOC_CHUNK; test_mac = (size_t) MAX_ALLOC_CHUNK;
if ((long) test_mac != 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); ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK);
max_to_use = jpeg_mem_init(cinfo); /* system-dependent initialization */ 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.free_pool = free_pool;
mem->pub.self_destruct = self_destruct; 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 */ /* Initialize working state */
mem->pub.max_memory_to_use = max_to_use; mem->pub.max_memory_to_use = max_to_use;

View File

@@ -1,271 +0,0 @@
/*
* jmemname.c
*
* Copyright (C) 1992-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 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

@@ -1,7 +1,7 @@
/* /*
* jmemnobs.c * jmemnobs.c
* *
* Copyright (C) 1992-1994, Thomas G. Lane. * Copyright (C) 1992-1996, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -31,13 +31,13 @@ extern void free JPP((void *ptr));
* routines malloc() and free(). * routines malloc() and free().
*/ */
GLOBAL void * GLOBAL(void *)
jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
{ {
return (void *) malloc(sizeofobject); return (void *) malloc(sizeofobject);
} }
GLOBAL void GLOBAL(void)
jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
{ {
free(object); free(object);
@@ -51,13 +51,13 @@ jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
* you probably won't be able to process useful-size images in only 64KB. * you probably won't be able to process useful-size images in only 64KB.
*/ */
GLOBAL void FAR * GLOBAL(void FAR *)
jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
{ {
return (void FAR *) malloc(sizeofobject); return (void FAR *) malloc(sizeofobject);
} }
GLOBAL void GLOBAL(void)
jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
{ {
free(object); free(object);
@@ -69,7 +69,7 @@ jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
* Here we always say, "we got all you want bud!" * Here we always say, "we got all you want bud!"
*/ */
GLOBAL long GLOBAL(long)
jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
long max_bytes_needed, long already_allocated) long max_bytes_needed, long already_allocated)
{ {
@@ -83,7 +83,7 @@ jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
* this should never be called and we can just error out. * this should never be called and we can just error out.
*/ */
GLOBAL void GLOBAL(void)
jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
long total_bytes_needed) long total_bytes_needed)
{ {
@@ -96,13 +96,13 @@ jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
* cleanup required. Here, there isn't any. * cleanup required. Here, there isn't any.
*/ */
GLOBAL long GLOBAL(long)
jpeg_mem_init (j_common_ptr cinfo) jpeg_mem_init (j_common_ptr cinfo)
{ {
return 0; /* just set max_memory_to_use to 0 */ return 0; /* just set max_memory_to_use to 0 */
} }
GLOBAL void GLOBAL(void)
jpeg_mem_term (j_common_ptr cinfo) jpeg_mem_term (j_common_ptr cinfo)
{ {
/* no work */ /* no work */

View File

@@ -1,7 +1,7 @@
/* /*
* jmemsys.h * jmemsys.h
* *
* Copyright (C) 1992-1994, Thomas G. Lane. * Copyright (C) 1992-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * 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 * in the IJG distribution. You may need to modify it if you write a
* custom memory manager. If system-dependent changes are needed in * custom memory manager. If system-dependent changes are needed in
* this file, the best method is to #ifdef them based on a configuration * 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.
*/ */
@@ -43,9 +44,9 @@
* On an 80x86 machine using small-data memory model, these manage near heap. * On an 80x86 machine using small-data memory model, these manage near heap.
*/ */
EXTERN void * jpeg_get_small JPP((j_common_ptr cinfo, size_t sizeofobject)); EXTERN(void *) jpeg_get_small JPP((j_common_ptr cinfo, size_t sizeofobject));
EXTERN void jpeg_free_small JPP((j_common_ptr cinfo, void * object, EXTERN(void) jpeg_free_small JPP((j_common_ptr cinfo, void * object,
size_t sizeofobject)); size_t sizeofobject));
/* /*
* These two functions are used to allocate and release large chunks of * These two functions are used to allocate and release large chunks of
@@ -56,9 +57,10 @@ EXTERN void jpeg_free_small JPP((j_common_ptr cinfo, void * object,
* in case a different allocation strategy is desirable for large chunks. * in case a different allocation strategy is desirable for large chunks.
*/ */
EXTERN void FAR * jpeg_get_large JPP((j_common_ptr cinfo,size_t sizeofobject)); EXTERN(void FAR *) jpeg_get_large JPP((j_common_ptr cinfo,
EXTERN void jpeg_free_large JPP((j_common_ptr cinfo, void FAR * object, size_t sizeofobject));
size_t sizeofobject)); EXTERN(void) jpeg_free_large JPP((j_common_ptr cinfo, void FAR * object,
size_t sizeofobject));
/* /*
* The macro MAX_ALLOC_CHUNK designates the maximum number of bytes that may * The macro MAX_ALLOC_CHUNK designates the maximum number of bytes that may
@@ -98,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. * Conversely, zero may be returned to always use the minimum amount of memory.
*/ */
EXTERN long jpeg_mem_available JPP((j_common_ptr cinfo, EXTERN(long) jpeg_mem_available JPP((j_common_ptr cinfo,
long min_bytes_needed, long min_bytes_needed,
long max_bytes_needed, long max_bytes_needed,
long already_allocated)); long already_allocated));
/* /*
@@ -113,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 */ #define TEMP_NAME_LENGTH 64 /* max length of a temporary file's name */
#ifdef USE_MSDOS_MEMMGR /* DOS-specific junk */ #ifdef USE_MSDOS_MEMMGR /* DOS-specific junk */
typedef unsigned short XMSH; /* type of extended-memory handles */ typedef unsigned short XMSH; /* type of extended-memory handles */
@@ -126,6 +129,11 @@ typedef union {
#endif /* USE_MSDOS_MEMMGR */ #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 * backing_store_ptr;
typedef struct backing_store_struct { typedef struct backing_store_struct {
@@ -146,13 +154,21 @@ typedef struct backing_store_struct {
/* For the MS-DOS manager (jmemdos.c), we need: */ /* For the MS-DOS manager (jmemdos.c), we need: */
handle_union handle; /* reference to backing-store storage object */ handle_union handle; /* reference to backing-store storage object */
char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */ 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 #else
/* For a typical implementation with temp files, we need: */ /* For a typical implementation with temp files, we need: */
FILE * temp_file; /* stdio reference to temp file */ FILE * temp_file; /* stdio reference to temp file */
char temp_name[TEMP_NAME_LENGTH]; /* name of temp file */ char temp_name[TEMP_NAME_LENGTH]; /* name of temp file */
#endif #endif
#endif
} backing_store_info; } backing_store_info;
/* /*
* Initial opening of a backing-store object. This must fill in the * Initial opening of a backing-store object. This must fill in the
* read/write/close pointers in the object. The read/write routines * read/write/close pointers in the object. The read/write routines
@@ -161,9 +177,9 @@ typedef struct backing_store_struct {
* just take an error exit.) * just take an error exit.)
*/ */
EXTERN void jpeg_open_backing_store JPP((j_common_ptr cinfo, EXTERN(void) jpeg_open_backing_store JPP((j_common_ptr cinfo,
backing_store_ptr info, backing_store_ptr info,
long total_bytes_needed)); long total_bytes_needed));
/* /*
@@ -178,5 +194,5 @@ EXTERN void jpeg_open_backing_store JPP((j_common_ptr cinfo,
* all opened backing-store objects have been closed. * all opened backing-store objects have been closed.
*/ */
EXTERN long jpeg_mem_init JPP((j_common_ptr cinfo)); EXTERN(long) jpeg_mem_init JPP((j_common_ptr cinfo));
EXTERN void jpeg_mem_term JPP((j_common_ptr cinfo)); EXTERN(void) jpeg_mem_term JPP((j_common_ptr cinfo));

View File

@@ -1,7 +1,8 @@
/* /*
* jmorecfg.h * jmorecfg.h
* *
* Copyright (C) 1991-1995, 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. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -62,11 +63,11 @@ typedef unsigned char JSAMPLE;
#else /* not HAVE_UNSIGNED_CHAR */ #else /* not HAVE_UNSIGNED_CHAR */
typedef char JSAMPLE; typedef char JSAMPLE;
#ifdef CHAR_IS_UNSIGNED #ifdef __CHAR_UNSIGNED__
#define GETJSAMPLE(value) ((int) (value)) #define GETJSAMPLE(value) ((int) (value))
#else #else
#define GETJSAMPLE(value) ((int) (value) & 0xFF) #define GETJSAMPLE(value) ((int) (value) & 0xFF)
#endif /* CHAR_IS_UNSIGNED */ #endif /* __CHAR_UNSIGNED__ */
#endif /* HAVE_UNSIGNED_CHAR */ #endif /* HAVE_UNSIGNED_CHAR */
@@ -113,11 +114,11 @@ typedef unsigned char JOCTET;
#else /* not HAVE_UNSIGNED_CHAR */ #else /* not HAVE_UNSIGNED_CHAR */
typedef char JOCTET; typedef char JOCTET;
#ifdef CHAR_IS_UNSIGNED #ifdef __CHAR_UNSIGNED__
#define GETJOCTET(value) (value) #define GETJOCTET(value) (value)
#else #else
#define GETJOCTET(value) ((value) & 0xFF) #define GETJOCTET(value) ((value) & 0xFF)
#endif /* CHAR_IS_UNSIGNED */ #endif /* __CHAR_UNSIGNED__ */
#endif /* HAVE_UNSIGNED_CHAR */ #endif /* HAVE_UNSIGNED_CHAR */
@@ -134,11 +135,11 @@ typedef char JOCTET;
#ifdef HAVE_UNSIGNED_CHAR #ifdef HAVE_UNSIGNED_CHAR
typedef unsigned char UINT8; typedef unsigned char UINT8;
#else /* not HAVE_UNSIGNED_CHAR */ #else /* not HAVE_UNSIGNED_CHAR */
#ifdef CHAR_IS_UNSIGNED #ifdef __CHAR_UNSIGNED__
typedef char UINT8; typedef char UINT8;
#else /* not CHAR_IS_UNSIGNED */ #else /* not __CHAR_UNSIGNED__ */
typedef short UINT8; typedef short UINT8;
#endif /* CHAR_IS_UNSIGNED */ #endif /* __CHAR_UNSIGNED__ */
#endif /* HAVE_UNSIGNED_CHAR */ #endif /* HAVE_UNSIGNED_CHAR */
/* UINT16 must hold at least the values 0..65535. */ /* UINT16 must hold at least the values 0..65535. */
@@ -173,16 +174,34 @@ typedef unsigned int JDIMENSION;
#define JPEG_MAX_DIMENSION 65500L /* a tad under 64K to prevent overflows */ #define JPEG_MAX_DIMENSION 65500L /* a tad under 64K to prevent overflows */
/* These defines are used in all function definitions and extern declarations. /* These macros are used in all function definitions and extern declarations.
* You could modify them if you need to change function linkage conventions. * You could modify them if you need to change function linkage conventions;
* in particular, you'll need to do that to make the library a Windows DLL.
* Another application is to make all functions global for use with debuggers * Another application is to make all functions global for use with debuggers
* or code profilers that require it. * or code profilers that require it.
*/ */
#define METHODDEF static /* a function called through method pointers */ /* a function called through method pointers: */
#define LOCAL static /* a function used only in its module */ #define METHODDEF(type) static type
#define GLOBAL /* a function referenced thru EXTERNs */ /* a function used only in its module: */
#define EXTERN extern /* a reference to a GLOBAL function */ #define LOCAL(type) static type
/* a function referenced thru EXTERNs: */
#define GLOBAL(type) type
/* a reference to a GLOBAL function: */
#define EXTERN(type) extern type
/* This macro is used to declare a "method", that is, a function pointer.
* We want to supply prototype parameters if the compiler can cope.
* Note that the arglist parameter must be parenthesized!
* Again, you can customize this if you need special linkage keywords.
*/
#ifdef HAVE_PROTOTYPES
#define JMETHOD(type,methodname,arglist) type (*methodname) arglist
#else
#define JMETHOD(type,methodname,arglist) type (*methodname) ()
#endif
/* Here is the pseudo-keyword for declaring pointers that must be "far" /* Here is the pseudo-keyword for declaring pointers that must be "far"
@@ -267,6 +286,7 @@ typedef int boolean;
#undef D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ #undef D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */
#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ #define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ #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 BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */
#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */ #define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */
#undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */ #undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */
@@ -297,31 +317,37 @@ typedef int boolean;
#define RGB_BLUE 2 /* Offset of Blue */ #define RGB_BLUE 2 /* Offset of Blue */
#define RGB_PIXELSIZE 3 /* JSAMPLEs per RGB scanline element */ #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. */ /* 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 /* On some machines (notably 68000 series) "int" is 32 bits, but multiplying
* two 16-bit shorts is faster than multiplying two ints. Define MULTIPLIER * 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. * as short on such a machine. MULTIPLIER must be at least 16 bits wide.
*/ */
#ifndef MULTIPLIER #ifndef MULTIPLIER
#ifndef WITH_SIMD
#define MULTIPLIER int /* type for fastest integer multiply */ #define MULTIPLIER int /* type for fastest integer multiply */
#else
#define MULTIPLIER short /* prefer 16-bit with SIMD for parellelism */
#endif
#endif #endif

102
jpegint.h
View File

@@ -1,7 +1,7 @@
/* /*
* jpegint.h * jpegint.h
* *
* Copyright (C) 1991-1995, Thomas G. Lane. * Copyright (C) 1991-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -118,15 +118,16 @@ struct jpeg_entropy_encoder {
/* Marker writing */ /* Marker writing */
struct jpeg_marker_writer { 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_file_header, (j_compress_ptr cinfo));
JMETHOD(void, write_frame_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_scan_header, (j_compress_ptr cinfo));
JMETHOD(void, write_file_trailer, (j_compress_ptr cinfo)); JMETHOD(void, write_file_trailer, (j_compress_ptr cinfo));
JMETHOD(void, write_tables_only, (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 +195,6 @@ struct jpeg_marker_reader {
JMETHOD(int, read_markers, (j_decompress_ptr cinfo)); JMETHOD(int, read_markers, (j_decompress_ptr cinfo));
/* Read a restart marker --- exported for use by entropy decoder only */ /* Read a restart marker --- exported for use by entropy decoder only */
jpeg_marker_parser_method read_restart_marker; 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 /* State of marker reader --- nominally internal, but applications
* supplying COM or APPn handlers might like to know the state. * supplying COM or APPn handlers might like to know the state.
@@ -212,6 +210,10 @@ struct jpeg_entropy_decoder {
JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
JMETHOD(boolean, decode_mcu, (j_decompress_ptr cinfo, JMETHOD(boolean, decode_mcu, (j_decompress_ptr cinfo,
JBLOCKROW *MCU_data)); 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) */ /* Inverse DCT (also performs dequantization) */
@@ -329,53 +331,55 @@ struct jpeg_color_quantizer {
/* Compression module initialization routines */ /* Compression module initialization routines */
EXTERN void jinit_compress_master JPP((j_compress_ptr cinfo)); EXTERN(void) jinit_compress_master JPP((j_compress_ptr cinfo));
EXTERN void jinit_c_master_control JPP((j_compress_ptr cinfo, EXTERN(void) jinit_c_master_control JPP((j_compress_ptr cinfo,
boolean transcode_only)); boolean transcode_only));
EXTERN void jinit_c_main_controller JPP((j_compress_ptr cinfo, EXTERN(void) jinit_c_main_controller JPP((j_compress_ptr cinfo,
boolean need_full_buffer)); boolean need_full_buffer));
EXTERN void jinit_c_prep_controller JPP((j_compress_ptr cinfo, EXTERN(void) jinit_c_prep_controller JPP((j_compress_ptr cinfo,
boolean need_full_buffer)); boolean need_full_buffer));
EXTERN void jinit_c_coef_controller JPP((j_compress_ptr cinfo, EXTERN(void) jinit_c_coef_controller JPP((j_compress_ptr cinfo,
boolean need_full_buffer)); boolean need_full_buffer));
EXTERN void jinit_color_converter JPP((j_compress_ptr cinfo)); EXTERN(void) jinit_color_converter JPP((j_compress_ptr cinfo));
EXTERN void jinit_downsampler JPP((j_compress_ptr cinfo)); EXTERN(void) jinit_downsampler JPP((j_compress_ptr cinfo));
EXTERN void jinit_forward_dct 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_huff_encoder JPP((j_compress_ptr cinfo));
EXTERN void jinit_phuff_encoder JPP((j_compress_ptr cinfo)); EXTERN(void) jinit_phuff_encoder JPP((j_compress_ptr cinfo));
EXTERN void jinit_marker_writer JPP((j_compress_ptr cinfo)); EXTERN(void) jinit_marker_writer JPP((j_compress_ptr cinfo));
/* Decompression module initialization routines */ /* Decompression module initialization routines */
EXTERN void jinit_master_decompress JPP((j_decompress_ptr cinfo)); EXTERN(void) jinit_master_decompress JPP((j_decompress_ptr cinfo));
EXTERN void jinit_d_main_controller JPP((j_decompress_ptr cinfo, EXTERN(void) jinit_d_main_controller JPP((j_decompress_ptr cinfo,
boolean need_full_buffer)); boolean need_full_buffer));
EXTERN void jinit_d_coef_controller JPP((j_decompress_ptr cinfo, EXTERN(void) jinit_d_coef_controller JPP((j_decompress_ptr cinfo,
boolean need_full_buffer)); boolean need_full_buffer));
EXTERN void jinit_d_post_controller JPP((j_decompress_ptr cinfo, EXTERN(void) jinit_d_post_controller JPP((j_decompress_ptr cinfo,
boolean need_full_buffer)); boolean need_full_buffer));
EXTERN void jinit_input_controller JPP((j_decompress_ptr cinfo)); EXTERN(void) jinit_input_controller JPP((j_decompress_ptr cinfo));
EXTERN void jinit_marker_reader 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_huff_decoder JPP((j_decompress_ptr cinfo));
EXTERN void jinit_phuff_decoder JPP((j_decompress_ptr cinfo)); EXTERN(void) jinit_phuff_decoder JPP((j_decompress_ptr cinfo));
EXTERN void jinit_inverse_dct 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_upsampler JPP((j_decompress_ptr cinfo));
EXTERN void jinit_color_deconverter JPP((j_decompress_ptr cinfo)); EXTERN(void) jinit_color_deconverter JPP((j_decompress_ptr cinfo));
EXTERN void jinit_1pass_quantizer JPP((j_decompress_ptr cinfo)); EXTERN(void) jinit_1pass_quantizer JPP((j_decompress_ptr cinfo));
EXTERN void jinit_2pass_quantizer JPP((j_decompress_ptr cinfo)); EXTERN(void) jinit_2pass_quantizer JPP((j_decompress_ptr cinfo));
EXTERN void jinit_merged_upsampler JPP((j_decompress_ptr cinfo)); EXTERN(void) jinit_merged_upsampler JPP((j_decompress_ptr cinfo));
/* Memory manager initialization */ /* Memory manager initialization */
EXTERN void jinit_memory_mgr JPP((j_common_ptr cinfo)); EXTERN(void) jinit_memory_mgr JPP((j_common_ptr cinfo));
/* Utility routines in jutils.c */ /* Utility routines in jutils.c */
EXTERN long jdiv_round_up JPP((long a, long b)); EXTERN(long) jdiv_round_up JPP((long a, long b));
EXTERN long jround_up JPP((long a, long b)); EXTERN(long) jround_up JPP((long a, long b));
EXTERN void jcopy_sample_rows JPP((JSAMPARRAY input_array, int source_row, EXTERN(void) jcopy_sample_rows JPP((JSAMPARRAY input_array, int source_row,
JSAMPARRAY output_array, int dest_row, JSAMPARRAY output_array, int dest_row,
int num_rows, JDIMENSION num_cols)); int num_rows, JDIMENSION num_cols));
EXTERN void jcopy_block_row JPP((JBLOCKROW input_row, JBLOCKROW output_row, EXTERN(void) jcopy_block_row JPP((JBLOCKROW input_row, JBLOCKROW output_row,
JDIMENSION num_blocks)); JDIMENSION num_blocks));
EXTERN void jzero_far JPP((void FAR * target, size_t bytestozero)); EXTERN(void) jzero_far JPP((void FAR * target, size_t bytestozero));
/* Constant tables in jutils.c */ /* 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 */ 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 */ extern const int jpeg_natural_order[]; /* zigzag coef order to natural order */
/* Suppress undefined-structure complaints if necessary. */ /* Suppress undefined-structure complaints if necessary. */

256
jpeglib.h
View File

@@ -1,7 +1,8 @@
/* /*
* jpeglib.h * jpeglib.h
* *
* Copyright (C) 1991-1995, Thomas G. Lane. * Copyright (C) 1991-1998, Thomas G. Lane.
* Copyright (C) 2009, D. R. Commander.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -13,6 +14,10 @@
#ifndef JPEGLIB_H #ifndef JPEGLIB_H
#define JPEGLIB_H #define JPEGLIB_H
#ifdef __cplusplus
extern "C" {
#endif
/* /*
* First we include the configuration files that record how this * First we include the configuration files that record how this
* installation of the JPEG library is set up. jconfig.h can be * installation of the JPEG library is set up. jconfig.h can be
@@ -30,7 +35,7 @@
* Might be useful for tests like "#if JPEG_LIB_VERSION >= 60". * Might be useful for tests like "#if JPEG_LIB_VERSION >= 60".
*/ */
#define JPEG_LIB_VERSION 60 /* Version 6 */ #define JPEG_LIB_VERSION 62 /* Version 6b */
/* Various constants determining the sizes of things. /* Various constants determining the sizes of things.
@@ -58,18 +63,6 @@
#endif #endif
/* This macro is used to declare a "method", that is, a function pointer.
* We want to supply prototype parameters if the compiler can cope.
* Note that the arglist parameter must be parenthesized!
*/
#ifdef HAVE_PROTOTYPES
#define JMETHOD(type,methodname,arglist) type (*methodname) arglist
#else
#define JMETHOD(type,methodname,arglist) type (*methodname) ()
#endif
/* Data structures for images (arrays of samples and of DCT coefficients). /* Data structures for images (arrays of samples and of DCT coefficients).
* On 80x86 machines, the image arrays are too big for near pointers, * On 80x86 machines, the image arrays are too big for near pointers,
* but the pointer arrays can fit in near memory. * but the pointer arrays can fit in near memory.
@@ -93,8 +86,9 @@ typedef JCOEF FAR *JCOEFPTR; /* useful in a couple of places */
/* DCT coefficient quantization tables. */ /* DCT coefficient quantization tables. */
typedef struct { typedef struct {
/* This field directly represents the contents of a JPEG DQT marker. /* This array gives the coefficient quantizers in natural array order
* Note: the values are always given in zigzag order. * (not the zigzag order in which they are stored in a JPEG DQT marker).
* CAUTION: IJG versions prior to v6a kept this array in zigzag order.
*/ */
UINT16 quantval[DCTSIZE2]; /* quantization step for each coefficient */ UINT16 quantval[DCTSIZE2]; /* quantization step for each coefficient */
/* This field is used only during compression. It's initialized FALSE when /* This field is used only during compression. It's initialized FALSE when
@@ -181,7 +175,7 @@ typedef struct {
/* Saved quantization table for component; NULL if none yet saved. /* Saved quantization table for component; NULL if none yet saved.
* See jdinput.c comments about the need for this information. * See jdinput.c comments about the need for this information.
* This field is not currently used by the compressor. * This field is currently used only for decompression.
*/ */
JQUANT_TBL * quant_table; JQUANT_TBL * quant_table;
@@ -199,16 +193,37 @@ typedef struct {
int Ah, Al; /* progressive JPEG successive approx. parms */ int Ah, Al; /* progressive JPEG successive approx. parms */
} jpeg_scan_info; } 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. */ /* Known color spaces. */
#define JCS_EXTENSIONS 1
typedef enum { typedef enum {
JCS_UNKNOWN, /* error/unspecified */ JCS_UNKNOWN, /* error/unspecified */
JCS_GRAYSCALE, /* monochrome */ 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_YCbCr, /* Y/Cb/Cr (also known as YUV) */
JCS_CMYK, /* C/M/Y/K */ 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; } J_COLOR_SPACE;
/* DCT/IDCT algorithm options. */ /* DCT/IDCT algorithm options. */
@@ -241,8 +256,9 @@ typedef enum {
struct jpeg_error_mgr * err; /* Error handler module */\ struct jpeg_error_mgr * err; /* Error handler module */\
struct jpeg_memory_mgr * mem; /* Memory manager module */\ struct jpeg_memory_mgr * mem; /* Memory manager module */\
struct jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\ struct jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\
boolean is_decompressor; /* so common code can tell which is which */\ void * client_data; /* Available for use by application */\
int global_state /* for checking call sequence validity */ 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 /* 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 * to receive a pointer to this structure. There are no actual instances of
@@ -333,6 +349,8 @@ struct jpeg_compress_struct {
/* Parameters controlling emission of special markers. */ /* Parameters controlling emission of special markers. */
boolean write_JFIF_header; /* should a JFIF marker be written? */ 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 */ /* These three values are not used by the JPEG code, merely copied */
/* into the JFIF APP0 marker. density_unit can be 0 for unknown, */ /* 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 */ /* 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect */
@@ -397,6 +415,8 @@ struct jpeg_compress_struct {
struct jpeg_downsampler * downsample; struct jpeg_downsampler * downsample;
struct jpeg_forward_dct * fdct; struct jpeg_forward_dct * fdct;
struct jpeg_entropy_encoder * entropy; struct jpeg_entropy_encoder * entropy;
jpeg_scan_info * script_space; /* workspace for jpeg_simple_progression */
int script_space_size;
}; };
@@ -542,7 +562,9 @@ struct jpeg_decompress_struct {
* the JPEG library. * the JPEG library.
*/ */
boolean saw_JFIF_marker; /* TRUE iff a JFIF APP0 marker was found */ 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 */ UINT8 density_unit; /* JFIF code for pixel size units */
UINT16 X_density; /* Horizontal pixel density */ UINT16 X_density; /* Horizontal pixel density */
UINT16 Y_density; /* Vertical pixel density */ UINT16 Y_density; /* Vertical pixel density */
@@ -551,6 +573,12 @@ struct jpeg_decompress_struct {
boolean CCIR601_sampling; /* TRUE=first samples are cosited */ 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 /* Remaining fields are known throughout decompressor, but generally
* should not be touched by a surrounding application. * should not be touched by a surrounding application.
*/ */
@@ -783,6 +811,9 @@ struct jpeg_memory_mgr {
* after creating the JPEG object. * after creating the JPEG object.
*/ */
long max_memory_to_use; long max_memory_to_use;
/* Maximum allocation request accepted by alloc_large. */
long max_alloc_chunk;
}; };
@@ -813,8 +844,8 @@ typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo));
#ifdef NEED_SHORT_EXTERNAL_NAMES #ifdef NEED_SHORT_EXTERNAL_NAMES
#define jpeg_std_error jStdError #define jpeg_std_error jStdError
#define jpeg_create_compress jCreaCompress #define jpeg_CreateCompress jCreaCompress
#define jpeg_create_decompress jCreaDecompress #define jpeg_CreateDecompress jCreaDecompress
#define jpeg_destroy_compress jDestCompress #define jpeg_destroy_compress jDestCompress
#define jpeg_destroy_decompress jDestDecompress #define jpeg_destroy_decompress jDestDecompress
#define jpeg_stdio_dest jStdDest #define jpeg_stdio_dest jStdDest
@@ -835,6 +866,8 @@ typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo));
#define jpeg_finish_compress jFinCompress #define jpeg_finish_compress jFinCompress
#define jpeg_write_raw_data jWrtRawData #define jpeg_write_raw_data jWrtRawData
#define jpeg_write_marker jWrtMarker #define jpeg_write_marker jWrtMarker
#define jpeg_write_m_header jWrtMHeader
#define jpeg_write_m_byte jWrtMByte
#define jpeg_write_tables jWrtTables #define jpeg_write_tables jWrtTables
#define jpeg_read_header jReadHeader #define jpeg_read_header jReadHeader
#define jpeg_start_decompress jStrtDecompress #define jpeg_start_decompress jStrtDecompress
@@ -848,6 +881,7 @@ typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo));
#define jpeg_new_colormap jNewCMap #define jpeg_new_colormap jNewCMap
#define jpeg_consume_input jConsumeInput #define jpeg_consume_input jConsumeInput
#define jpeg_calc_output_dimensions jCalcDimensions #define jpeg_calc_output_dimensions jCalcDimensions
#define jpeg_save_markers jSaveMarkers
#define jpeg_set_marker_processor jSetMarker #define jpeg_set_marker_processor jSetMarker
#define jpeg_read_coefficients jReadCoefs #define jpeg_read_coefficients jReadCoefs
#define jpeg_write_coefficients jWrtCoefs #define jpeg_write_coefficients jWrtCoefs
@@ -861,65 +895,86 @@ typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo));
/* Default error-management setup */ /* Default error-management setup */
EXTERN struct jpeg_error_mgr *jpeg_std_error JPP((struct jpeg_error_mgr *err)); EXTERN(struct jpeg_error_mgr *) jpeg_std_error
JPP((struct jpeg_error_mgr * err));
/* Initialization and destruction of JPEG compression objects */ /* Initialization of JPEG compression objects.
/* NB: you must set up the error-manager BEFORE calling jpeg_create_xxx */ * jpeg_create_compress() and jpeg_create_decompress() are the exported
EXTERN void jpeg_create_compress JPP((j_compress_ptr cinfo)); * names that applications should call. These expand to calls on
EXTERN void jpeg_create_decompress JPP((j_decompress_ptr cinfo)); * jpeg_CreateCompress and jpeg_CreateDecompress with additional information
EXTERN void jpeg_destroy_compress JPP((j_compress_ptr cinfo)); * passed for version mismatch checking.
EXTERN void jpeg_destroy_decompress JPP((j_decompress_ptr cinfo)); * NB: you must set up the error-manager BEFORE calling jpeg_create_xxx.
*/
#define jpeg_create_compress(cinfo) \
jpeg_CreateCompress((cinfo), JPEG_LIB_VERSION, \
(size_t) sizeof(struct jpeg_compress_struct))
#define jpeg_create_decompress(cinfo) \
jpeg_CreateDecompress((cinfo), JPEG_LIB_VERSION, \
(size_t) sizeof(struct jpeg_decompress_struct))
EXTERN(void) jpeg_CreateCompress JPP((j_compress_ptr cinfo,
int version, size_t structsize));
EXTERN(void) jpeg_CreateDecompress JPP((j_decompress_ptr cinfo,
int version, size_t structsize));
/* Destruction of JPEG compression objects */
EXTERN(void) jpeg_destroy_compress JPP((j_compress_ptr cinfo));
EXTERN(void) jpeg_destroy_decompress JPP((j_decompress_ptr cinfo));
/* Standard data source and destination managers: stdio streams. */ /* Standard data source and destination managers: stdio streams. */
/* Caller is responsible for opening the file before and closing after. */ /* Caller is responsible for opening the file before and closing after. */
EXTERN void jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile)); EXTERN(void) jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile));
EXTERN void jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile)); EXTERN(void) jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile));
/* Default parameter setup for compression */ /* Default parameter setup for compression */
EXTERN void jpeg_set_defaults JPP((j_compress_ptr cinfo)); EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo));
/* Compression parameter setup aids */ /* Compression parameter setup aids */
EXTERN void jpeg_set_colorspace JPP((j_compress_ptr cinfo, EXTERN(void) jpeg_set_colorspace JPP((j_compress_ptr cinfo,
J_COLOR_SPACE colorspace)); J_COLOR_SPACE colorspace));
EXTERN void jpeg_default_colorspace JPP((j_compress_ptr cinfo)); EXTERN(void) jpeg_default_colorspace JPP((j_compress_ptr cinfo));
EXTERN void jpeg_set_quality JPP((j_compress_ptr cinfo, int quality, EXTERN(void) jpeg_set_quality JPP((j_compress_ptr cinfo, int quality,
boolean force_baseline)); boolean force_baseline));
EXTERN void jpeg_set_linear_quality JPP((j_compress_ptr cinfo, EXTERN(void) jpeg_set_linear_quality JPP((j_compress_ptr cinfo,
int scale_factor, int scale_factor,
boolean force_baseline)); boolean force_baseline));
EXTERN void jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl, EXTERN(void) jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl,
const unsigned int *basic_table, const unsigned int *basic_table,
int scale_factor, int scale_factor,
boolean force_baseline)); boolean force_baseline));
EXTERN int jpeg_quality_scaling JPP((int quality)); EXTERN(int) jpeg_quality_scaling JPP((int quality));
EXTERN void jpeg_simple_progression JPP((j_compress_ptr cinfo)); EXTERN(void) jpeg_simple_progression JPP((j_compress_ptr cinfo));
EXTERN void jpeg_suppress_tables JPP((j_compress_ptr cinfo, EXTERN(void) jpeg_suppress_tables JPP((j_compress_ptr cinfo,
boolean suppress)); boolean suppress));
EXTERN JQUANT_TBL * jpeg_alloc_quant_table JPP((j_common_ptr cinfo)); EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table JPP((j_common_ptr cinfo));
EXTERN JHUFF_TBL * jpeg_alloc_huff_table JPP((j_common_ptr cinfo)); EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table JPP((j_common_ptr cinfo));
/* Main entry points for compression */ /* Main entry points for compression */
EXTERN void jpeg_start_compress JPP((j_compress_ptr cinfo, EXTERN(void) jpeg_start_compress JPP((j_compress_ptr cinfo,
boolean write_all_tables)); boolean write_all_tables));
EXTERN JDIMENSION jpeg_write_scanlines JPP((j_compress_ptr cinfo, EXTERN(JDIMENSION) jpeg_write_scanlines JPP((j_compress_ptr cinfo,
JSAMPARRAY scanlines, JSAMPARRAY scanlines,
JDIMENSION num_lines)); JDIMENSION num_lines));
EXTERN void jpeg_finish_compress JPP((j_compress_ptr cinfo)); EXTERN(void) jpeg_finish_compress JPP((j_compress_ptr cinfo));
/* Replaces jpeg_write_scanlines when writing raw downsampled data. */ /* Replaces jpeg_write_scanlines when writing raw downsampled data. */
EXTERN JDIMENSION jpeg_write_raw_data JPP((j_compress_ptr cinfo, EXTERN(JDIMENSION) jpeg_write_raw_data JPP((j_compress_ptr cinfo,
JSAMPIMAGE data, JSAMPIMAGE data,
JDIMENSION num_lines)); JDIMENSION num_lines));
/* Write a special marker. See libjpeg.doc concerning safe usage. */ /* Write a special marker. See libjpeg.doc concerning safe usage. */
EXTERN void jpeg_write_marker JPP((j_compress_ptr cinfo, int marker, EXTERN(void) jpeg_write_marker
const JOCTET *dataptr, unsigned int datalen)); 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 */ /* Alternate compression function: just write an abbreviated table file */
EXTERN void jpeg_write_tables JPP((j_compress_ptr cinfo)); EXTERN(void) jpeg_write_tables JPP((j_compress_ptr cinfo));
/* Decompression startup: read start of JPEG datastream to see what's there */ /* Decompression startup: read start of JPEG datastream to see what's there */
EXTERN int jpeg_read_header JPP((j_decompress_ptr cinfo, EXTERN(int) jpeg_read_header JPP((j_decompress_ptr cinfo,
boolean require_image)); boolean require_image));
/* Return value is one of: */ /* Return value is one of: */
#define JPEG_SUSPENDED 0 /* Suspended due to lack of input data */ #define JPEG_SUSPENDED 0 /* Suspended due to lack of input data */
#define JPEG_HEADER_OK 1 /* Found valid image datastream */ #define JPEG_HEADER_OK 1 /* Found valid image datastream */
@@ -931,25 +986,25 @@ EXTERN int jpeg_read_header JPP((j_decompress_ptr cinfo,
*/ */
/* Main entry points for decompression */ /* Main entry points for decompression */
EXTERN boolean jpeg_start_decompress JPP((j_decompress_ptr cinfo)); EXTERN(boolean) jpeg_start_decompress JPP((j_decompress_ptr cinfo));
EXTERN JDIMENSION jpeg_read_scanlines JPP((j_decompress_ptr cinfo, EXTERN(JDIMENSION) jpeg_read_scanlines JPP((j_decompress_ptr cinfo,
JSAMPARRAY scanlines, JSAMPARRAY scanlines,
JDIMENSION max_lines)); JDIMENSION max_lines));
EXTERN boolean jpeg_finish_decompress JPP((j_decompress_ptr cinfo)); EXTERN(boolean) jpeg_finish_decompress JPP((j_decompress_ptr cinfo));
/* Replaces jpeg_read_scanlines when reading raw downsampled data. */ /* Replaces jpeg_read_scanlines when reading raw downsampled data. */
EXTERN JDIMENSION jpeg_read_raw_data JPP((j_decompress_ptr cinfo, EXTERN(JDIMENSION) jpeg_read_raw_data JPP((j_decompress_ptr cinfo,
JSAMPIMAGE data, JSAMPIMAGE data,
JDIMENSION max_lines)); JDIMENSION max_lines));
/* Additional entry points for buffered-image mode. */ /* Additional entry points for buffered-image mode. */
EXTERN boolean jpeg_has_multiple_scans JPP((j_decompress_ptr cinfo)); EXTERN(boolean) jpeg_has_multiple_scans JPP((j_decompress_ptr cinfo));
EXTERN boolean jpeg_start_output JPP((j_decompress_ptr cinfo, EXTERN(boolean) jpeg_start_output JPP((j_decompress_ptr cinfo,
int scan_number)); int scan_number));
EXTERN boolean jpeg_finish_output JPP((j_decompress_ptr cinfo)); EXTERN(boolean) jpeg_finish_output JPP((j_decompress_ptr cinfo));
EXTERN boolean jpeg_input_complete JPP((j_decompress_ptr cinfo)); EXTERN(boolean) jpeg_input_complete JPP((j_decompress_ptr cinfo));
EXTERN void jpeg_new_colormap JPP((j_decompress_ptr cinfo)); EXTERN(void) jpeg_new_colormap JPP((j_decompress_ptr cinfo));
EXTERN int jpeg_consume_input JPP((j_decompress_ptr cinfo)); EXTERN(int) jpeg_consume_input JPP((j_decompress_ptr cinfo));
/* Return value is one of: */ /* Return value is one of: */
/* #define JPEG_SUSPENDED 0 Suspended due to lack of input data */ /* #define JPEG_SUSPENDED 0 Suspended due to lack of input data */
#define JPEG_REACHED_SOS 1 /* Reached start of new scan */ #define JPEG_REACHED_SOS 1 /* Reached start of new scan */
@@ -958,19 +1013,24 @@ EXTERN int jpeg_consume_input JPP((j_decompress_ptr cinfo));
#define JPEG_SCAN_COMPLETED 4 /* Completed last iMCU row of a scan */ #define JPEG_SCAN_COMPLETED 4 /* Completed last iMCU row of a scan */
/* Precalculate output dimensions for current decompression parameters. */ /* Precalculate output dimensions for current decompression parameters. */
EXTERN void jpeg_calc_output_dimensions JPP((j_decompress_ptr cinfo)); 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. */ /* Install a special processing method for COM or APPn markers. */
EXTERN void jpeg_set_marker_processor JPP((j_decompress_ptr cinfo, EXTERN(void) jpeg_set_marker_processor
int marker_code, JPP((j_decompress_ptr cinfo, int marker_code,
jpeg_marker_parser_method routine)); jpeg_marker_parser_method routine));
/* Read or write raw DCT coefficients --- useful for lossless transcoding. */ /* Read or write raw DCT coefficients --- useful for lossless transcoding. */
EXTERN jvirt_barray_ptr * jpeg_read_coefficients JPP((j_decompress_ptr cinfo)); EXTERN(jvirt_barray_ptr *) jpeg_read_coefficients JPP((j_decompress_ptr cinfo));
EXTERN void jpeg_write_coefficients JPP((j_compress_ptr cinfo, EXTERN(void) jpeg_write_coefficients JPP((j_compress_ptr cinfo,
jvirt_barray_ptr * coef_arrays)); jvirt_barray_ptr * coef_arrays));
EXTERN void jpeg_copy_critical_parameters JPP((j_decompress_ptr srcinfo, EXTERN(void) jpeg_copy_critical_parameters JPP((j_decompress_ptr srcinfo,
j_compress_ptr dstinfo)); j_compress_ptr dstinfo));
/* If you choose to abort compression or decompression before completing /* If you choose to abort compression or decompression before completing
* jpeg_finish_(de)compress, then you need to clean up to release memory, * jpeg_finish_(de)compress, then you need to clean up to release memory,
@@ -978,18 +1038,18 @@ EXTERN void jpeg_copy_critical_parameters JPP((j_decompress_ptr srcinfo,
* if you're done with the JPEG object, but if you want to clean it up and * if you're done with the JPEG object, but if you want to clean it up and
* reuse it, call this: * reuse it, call this:
*/ */
EXTERN void jpeg_abort_compress JPP((j_compress_ptr cinfo)); EXTERN(void) jpeg_abort_compress JPP((j_compress_ptr cinfo));
EXTERN void jpeg_abort_decompress JPP((j_decompress_ptr cinfo)); EXTERN(void) jpeg_abort_decompress JPP((j_decompress_ptr cinfo));
/* Generic versions of jpeg_abort and jpeg_destroy that work on either /* Generic versions of jpeg_abort and jpeg_destroy that work on either
* flavor of JPEG object. These may be more convenient in some places. * flavor of JPEG object. These may be more convenient in some places.
*/ */
EXTERN void jpeg_abort JPP((j_common_ptr cinfo)); EXTERN(void) jpeg_abort JPP((j_common_ptr cinfo));
EXTERN void jpeg_destroy JPP((j_common_ptr cinfo)); EXTERN(void) jpeg_destroy JPP((j_common_ptr cinfo));
/* Default restart-marker-resync procedure for use by data source modules */ /* Default restart-marker-resync procedure for use by data source modules */
EXTERN boolean jpeg_resync_to_restart JPP((j_decompress_ptr cinfo, EXTERN(boolean) jpeg_resync_to_restart JPP((j_decompress_ptr cinfo,
int desired)); int desired));
/* These marker codes are exported since applications and data source modules /* These marker codes are exported since applications and data source modules
@@ -1047,4 +1107,8 @@ struct jpeg_color_quantizer { long dummy; };
#include "jerror.h" /* fetch error codes too */ #include "jerror.h" /* fetch error codes too */
#endif #endif
#ifdef __cplusplus
}
#endif
#endif /* JPEGLIB_H */ #endif /* JPEGLIB_H */

View File

@@ -1,6 +1,6 @@
.TH JPEGTRAN 1 "15 June 1995" .TH JPEGTRAN 1 "3 August 1997"
.SH NAME .SH NAME
jpegtran \- lossless transcoding of JPEG files jpegtran \- lossless transformation of JPEG files
.SH SYNOPSIS .SH SYNOPSIS
.B jpegtran .B jpegtran
[ [
@@ -13,23 +13,27 @@ jpegtran \- lossless transcoding of JPEG files
.SH DESCRIPTION .SH DESCRIPTION
.LP .LP
.B jpegtran .B jpegtran
translates JPEG files from one variant of JPEG to another, for example performs various useful transformations of JPEG files.
from baseline JPEG to progressive JPEG. The transformation is lossless: It can translate the coded representation from one variant of JPEG to another,
no image degradation occurs, which would not be true if you used 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 .B djpeg
followed by followed by
.BR cjpeg . .B cjpeg
However, you cannot alter the image quality, because that would not be to accomplish the same conversion. But by the same token,
a lossless operation. .B jpegtran
cannot perform lossy operations such as changing the image quality.
.PP
.B jpegtran .B jpegtran
reads the named JPEG/JFIF file, or the standard input if no file is 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. named, and produces a JPEG/JFIF file on the standard output.
.SH OPTIONS .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, All switch names may be abbreviated; for example,
.B \-optimize .B \-optimize
may be written may be written
@@ -41,41 +45,131 @@ British spellings are also accepted (e.g.,
.BR \-optimise ), .BR \-optimise ),
though for brevity these are not mentioned below. though for brevity these are not mentioned below.
.PP .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 .TP
.B \-optimize .B \-optimize
Perform optimization of entropy encoding parameters. Without this, default Perform optimization of entropy encoding parameters.
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 .
.TP .TP
.B \-progressive .B \-progressive
Create progressive JPEG file (see below). Create progressive JPEG file.
.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:
.TP .TP
.BI \-restart " N" .BI \-restart " N"
Emit a JPEG restart marker every N MCU rows, or every N MCU blocks if "B" is Emit a JPEG restart marker every N MCU rows, or every N MCU blocks if "B" is
attached to the number. attached to the number.
.B \-restart 0 .TP
(the default) means no restart markers. .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.
.PP
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.
.PP
Another not-strictly-lossless transformation switch is:
.TP
.B \-grayscale
Force grayscale output.
.PP
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 inessential data.
.TP
.B \-copy all
Copy all extra markers. This setting preserves miscellaneous markers
found in the source file, such as JFIF thumbnails and Photoshop settings.
In some files these extra markers can be sizable.
.PP
The default behavior is
.BR "\-copy comments" .
(Note: in IJG releases v6 and v6a,
.B jpegtran
always did the equivalent of
.BR "\-copy none" .)
.PP
Additional switches recognized by jpegtran are:
.TP .TP
.BI \-maxmemory " N" .BI \-maxmemory " N"
Set limit for amount of memory to use in processing large images. Value is Set limit for amount of memory to use in processing large images. Value is
@@ -95,26 +189,6 @@ give more output. Also, version information is printed at startup.
.B \-debug .B \-debug
Same as Same as
.BR \-verbose . .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 .SH EXAMPLES
.LP .LP
This example converts a baseline JPEG file to progressive form: This example converts a baseline JPEG file to progressive form:
@@ -123,6 +197,14 @@ This example converts a baseline JPEG file to progressive form:
.I foo.jpg .I foo.jpg
.B > .B >
.I fooprog.jpg .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 .SH ENVIRONMENT
.TP .TP
.B JPEGMEM .B JPEGMEM
@@ -147,4 +229,10 @@ Independent JPEG Group
.SH BUGS .SH BUGS
Arithmetic coding is not supported for legal reasons. Arithmetic coding is not supported for legal reasons.
.PP .PP
Still not as fast as we'd like. The transform options can't transform odd-size images perfectly. Use
.B \-trim
if you don't like the results without it.
.PP
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,21 +1,24 @@
/* /*
* jpegtran.c * jpegtran.c
* *
* Copyright (C) 1995, Thomas G. Lane. * Copyright (C) 1995-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
* This file contains a command-line user interface for JPEG transcoding. * This file contains a command-line user interface for JPEG transcoding.
* It is very similar to cjpeg.c, but provides lossless transcoding between * It is very similar to cjpeg.c, but provides lossless transcoding between
* different JPEG file formats. * 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 "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
#include "transupp.h" /* Support routines for jpegtran */
#include "jversion.h" /* for version message */ #include "jversion.h" /* for version message */
#ifdef USE_CCOMMAND /* command-line reader for Macintosh */ #ifdef USE_CCOMMAND /* command-line reader for Macintosh */
#ifdef __MWERKS__ #ifdef __MWERKS__
#include <SIOUX.h> /* Metrowerks declares it here */ #include <SIOUX.h> /* Metrowerks needs this */
#include <console.h> /* ... and this */
#endif #endif
#ifdef THINK_C #ifdef THINK_C
#include <console.h> /* Think declares it here */ #include <console.h> /* Think declares it here */
@@ -34,9 +37,11 @@
static const char * progname; /* program name for error messages */ static const char * progname; /* program name for error messages */
static char * outfilename; /* for -outfile switch */ static char * outfilename; /* for -outfile switch */
static JCOPY_OPTION copyoption; /* -copy switch */
static jpeg_transform_info transformoption; /* image transformation options */
LOCAL void LOCAL(void)
usage (void) usage (void)
/* complain about bad command line */ /* complain about bad command line */
{ {
@@ -48,12 +53,24 @@ usage (void)
#endif #endif
fprintf(stderr, "Switches (names may be abbreviated):\n"); 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 #ifdef ENTROPY_OPT_SUPPORTED
fprintf(stderr, " -optimize Optimize Huffman table (smaller file, but slow compression)\n"); fprintf(stderr, " -optimize Optimize Huffman table (smaller file, but slow compression)\n");
#endif #endif
#ifdef C_PROGRESSIVE_SUPPORTED #ifdef C_PROGRESSIVE_SUPPORTED
fprintf(stderr, " -progressive Create progressive JPEG file\n"); fprintf(stderr, " -progressive Create progressive JPEG file\n");
#endif #endif
#if TRANSFORMS_SUPPORTED
fprintf(stderr, "Switches for modifying the image:\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, " -rotate [90|180|270] Rotate image (degrees clockwise)\n");
fprintf(stderr, " -transpose Transpose image\n");
fprintf(stderr, " -transverse Transverse transpose image\n");
fprintf(stderr, " -trim Drop non-transformable edge blocks\n");
#endif /* TRANSFORMS_SUPPORTED */
fprintf(stderr, "Switches for advanced users:\n"); fprintf(stderr, "Switches for advanced users:\n");
fprintf(stderr, " -restart N Set restart interval in rows, or in blocks with B\n"); fprintf(stderr, " -restart N Set restart interval in rows, or in blocks with B\n");
fprintf(stderr, " -maxmemory N Maximum memory to use (in kbytes)\n"); fprintf(stderr, " -maxmemory N Maximum memory to use (in kbytes)\n");
@@ -70,7 +87,30 @@ usage (void)
} }
LOCAL int 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, parse_switches (j_compress_ptr cinfo, int argc, char **argv,
int last_file_arg_seen, boolean for_real) int last_file_arg_seen, boolean for_real)
/* Parse optional switches. /* Parse optional switches.
@@ -90,6 +130,10 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
/* Set up default JPEG parameters. */ /* Set up default JPEG parameters. */
simple_progressive = FALSE; simple_progressive = FALSE;
outfilename = NULL; outfilename = NULL;
copyoption = JCOPYOPT_DEFAULT;
transformoption.transform = JXFORM_NONE;
transformoption.trim = FALSE;
transformoption.force_grayscale = FALSE;
cinfo->err->trace_level = 0; cinfo->err->trace_level = 0;
/* Scan command line options, adjust parameters */ /* Scan command line options, adjust parameters */
@@ -116,6 +160,19 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
#endif #endif
} else if (keymatch(arg, "copy", 1)) {
/* 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, "debug", 1) || keymatch(arg, "verbose", 1)) { } else if (keymatch(arg, "debug", 1) || keymatch(arg, "verbose", 1)) {
/* Enable debug printouts. */ /* Enable debug printouts. */
/* On first -d, print version identification */ /* On first -d, print version identification */
@@ -128,6 +185,25 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
} }
cinfo->err->trace_level++; 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)) { } else if (keymatch(arg, "maxmemory", 3)) {
/* Maximum memory in Kb (or Mb with 'm'). */ /* Maximum memory in Kb (or Mb with 'm'). */
long lval; long lval;
@@ -187,7 +263,20 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
/* restart_interval will be computed during startup */ /* 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. */ /* Set scan script. */
#ifdef C_MULTISCAN_FILES_SUPPORTED #ifdef C_MULTISCAN_FILES_SUPPORTED
if (++argn >= argc) /* advance to next argument */ if (++argn >= argc) /* advance to next argument */
@@ -200,6 +289,18 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
#endif #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 { } else {
usage(); /* bogus switch */ usage(); /* bogus switch */
} }
@@ -229,7 +330,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
* The main program. * The main program.
*/ */
GLOBAL int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
struct jpeg_decompress_struct srcinfo; struct jpeg_decompress_struct srcinfo;
@@ -238,7 +339,8 @@ main (int argc, char **argv)
#ifdef PROGRESS_REPORT #ifdef PROGRESS_REPORT
struct cdjpeg_progress_mgr progress; struct cdjpeg_progress_mgr progress;
#endif #endif
jvirt_barray_ptr * coef_arrays; jvirt_barray_ptr * src_coef_arrays;
jvirt_barray_ptr * dst_coef_arrays;
int file_index; int file_index;
FILE * input_file; FILE * input_file;
FILE * output_file; FILE * output_file;
@@ -268,12 +370,15 @@ main (int argc, char **argv)
/* Scan command line to find file names. /* Scan command line to find file names.
* It is convenient to use just one switch-parsing routine, but the switch * 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 * values read here are mostly ignored; we will rescan the switches after
* the input file. * 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); file_index = parse_switches(&dstinfo, argc, argv, 0, FALSE);
jsrcerr.trace_level = jdsterr.trace_level; jsrcerr.trace_level = jdsterr.trace_level;
srcinfo.mem->max_memory_to_use = dstinfo.mem->max_memory_to_use;
#ifdef TWO_FILE_COMMANDLINE #ifdef TWO_FILE_COMMANDLINE
/* Must have either -outfile switch or explicit output file name */ /* Must have either -outfile switch or explicit output file name */
@@ -328,25 +433,54 @@ main (int argc, char **argv)
/* Specify data source for decompression */ /* Specify data source for decompression */
jpeg_stdio_src(&srcinfo, input_file); jpeg_stdio_src(&srcinfo, input_file);
/* Enable saving of extra markers that we want to copy */
jcopy_markers_setup(&srcinfo, copyoption);
/* Read file header */ /* Read file header */
(void) jpeg_read_header(&srcinfo, TRUE); (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
jtransform_request_workspace(&srcinfo, &transformoption);
#endif
/* Read source file as DCT coefficients */ /* 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 */ /* Initialize destination compression parameters from source values */
jpeg_copy_critical_parameters(&srcinfo, &dstinfo); 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
/* Adjust default compression parameters by re-parsing the options */ /* Adjust default compression parameters by re-parsing the options */
file_index = parse_switches(&dstinfo, argc, argv, 0, TRUE); file_index = parse_switches(&dstinfo, argc, argv, 0, TRUE);
/* Specify data destination for compression */ /* Specify data destination for compression */
jpeg_stdio_dest(&dstinfo, output_file); jpeg_stdio_dest(&dstinfo, output_file);
/* Start compressor */ /* Start compressor (note no image data is actually written here) */
jpeg_write_coefficients(&dstinfo, coef_arrays); 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 */ /* Finish compression and release memory */
jpeg_finish_compress(&dstinfo); jpeg_finish_compress(&dstinfo);

387
jpegut.c Normal file
View File

@@ -0,0 +1,387 @@
/* Copyright (C)2004 Landmark Graphics Corporation
* Copyright (C)2005 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.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "./rrtimer.h"
#include "./turbojpeg.h"
#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"};
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);
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(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;
}
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(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";}
}
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;
sprintf(tempstr, "%s_enc_%s_%s_%sQ%d.jpg", basefilename, pixformat,
(flags&TJ_BOTTOMUP)? "BU":"TD", _subnames[subsamp], qual);
writejpeg(jpegbuf, *size, tempstr);
printf("Done. %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 qual, int flags)
{
unsigned char *bmpbuf=NULL;
const char *pixformat; int _w=0, _h=0; double t;
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";}
}
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((bmpbuf=(unsigned char *)malloc(w*h*ps+1))==NULL)
{
printf("ERROR: Could not allocate buffer\n"); bailout();
}
memset(bmpbuf, 0, w*ps*h);
t=rrtime();
_catch(tjDecompress(hnd, jpegbuf, jpegsize, bmpbuf, w, w*ps, h, ps, flags));
t=rrtime()-t;
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, 100, 0);
gentestjpeg(hnd, jpegbuf, &size, w, h, ps, basefilename, subsamp, 100, TJ_BGR);
gentestbmp(dhnd, jpegbuf, size, w, h, ps, basefilename, subsamp, 100, TJ_BGR);
gentestjpeg(hnd, jpegbuf, &size, w, h, ps, basefilename, subsamp, 100, TJ_BOTTOMUP);
gentestbmp(dhnd, jpegbuf, size, w, h, ps, basefilename, subsamp, 100, 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, 100, 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, 100, 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, 100, 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, 100, 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, 100, 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[])
{
dotest(35, 41, 3, TJ_444, "test");
dotest(35, 41, 4, TJ_444, "test");
dotest(35, 41, 3, TJ_GRAYSCALE, "test");
dotest(35, 41, 4, TJ_GRAYSCALE, "test");
dotest1();
return exitstatus;
}

392
jpgtest.cxx Normal file
View File

@@ -0,0 +1,392 @@
/* Copyright (C)2004 Landmark Graphics Corporation
* Copyright (C)2005, 2006 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.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "./bmp.h"
#include "./rrutil.h"
#include "./rrtimer.h"
#include "./turbojpeg.h"
#define _catch(f) {if((f)==-1) {printf("Error in %s:\n%s\n", #f, tjGetErrorStr()); goto bailout;}}
int forcemmx=0, forcesse=0, forcesse2=0, forcesse3=0, fastupsample=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"};
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; 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;
flags |= _flags[pf];
if(bu) flags |= TJ_BOTTOMUP;
if((rgbbuf=(unsigned char *)malloc(pitch*h)) == NULL)
{
puts("ERROR: Could not allocate image buffer.");
exit(1);
}
if(!quiet) printf("\n>>>>> %s (%s) <--> JPEG %s Q%d <<<<<\n", _pfname[pf],
bu?"Bottom-up":"Top-down", _subnamel[jpegsub], qual);
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)
{
puts("ERROR: Could not allocate image buffers.");
goto bailout;
}
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)
{
puts("ERROR: Could not allocate image buffers.");
goto bailout;
}
}
// 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)
{
printf("Error in tjInitCompress():\n%s\n", tjGetErrorStr());
goto bailout;
}
_catch(tjCompress(hnd, rgbbuf, tilesizex, pitch, tilesizey, ps,
jpegbuf[0], &comptilesize[0], jpegsub, qual, flags));
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);
_catch(tjCompress(hnd, &rgbbuf[pitch*i+j*ps], tempw, pitch,
temph, ps, jpegbuf[tilen], &comptilesize[tilen], jpegsub, qual,
flags));
jpgbufsize+=comptilesize[tilen];
tilen++;
}
}
ITER++;
} while((elapsed=timer.elapsed())<5.);
_catch(tjDestroy(hnd));
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)
{
sprintf(tempstr, "%s_%sQ%d.jpg", filename, _subnames[jpegsub], qual);
if((outfile=fopen(tempstr, "wb"))==NULL)
{
puts("ERROR: Could not open reference image");
exit(1);
}
if(fwrite(jpegbuf[0], jpgbufsize, 1, outfile)!=1)
{
puts("ERROR: Could not write reference image");
exit(1);
}
fclose(outfile);
if(!quiet) printf("Reference image written to %s\n", tempstr);
}
// Decompression test
memset(rgbbuf, 127, pitch*h); // Grey image means decompressor did nothing
if((hnd=tjInitDecompress())==NULL)
{
printf("Error in tjInitDecompress():\n%s\n", tjGetErrorStr());
goto bailout;
}
_catch(tjDecompress(hnd, jpegbuf[0], jpgbufsize, rgbbuf, tilesizex, pitch,
tilesizey, ps, flags));
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);
_catch(tjDecompress(hnd, jpegbuf[tilen], comptilesize[tilen],
&rgbbuf[pitch*i+ps*j], tempw, pitch, temph, ps, flags));
tilen++;
}
}
ITER++;
} while((elapsed=timer.elapsed())<5.);
_catch(tjDestroy(hnd));
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(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)
{
printf("ERROR saving bitmap: %s\n", bmpgeterr());
goto bailout;
}
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)
{
printf("ERROR saving bitmap: %s\n", bmpgeterr());
goto bailout;
}
// Cleanup
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(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;}
return;
}
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;
printf("\n");
if(argc<3)
{
printf("USAGE: %s <Inputfile (BMP|PPM)> <%% Quality>\n\n", argv[0]);
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(" 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);
}
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>3)
{
for(i=3; 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(loadbmp(argv[1], &bmpbuf, &w, &h, pf, 1, bu)==-1)
{
printf("ERROR loading bitmap: %s\n", bmpgeterr()); exit(1);
}
temp=strrchr(argv[1], '.');
if(temp!=NULL)
{
if(!stricmp(temp, ".ppm")) useppm=1;
*temp='\0';
}
if(quiet)
{
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");
}
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);
if(bmpbuf) free(bmpbuf);
return 0;
}

View File

@@ -1,7 +1,8 @@
/* /*
* jquant1.c * jquant1.c
* *
* Copyright (C) 1991-1995, Thomas G. Lane. * Copyright (C) 1991-1996, Thomas G. Lane.
* Copyright (C) 2009, D. R. Commander
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@@ -182,7 +183,7 @@ typedef my_cquantizer * my_cquantize_ptr;
*/ */
LOCAL int LOCAL(int)
select_ncolors (j_decompress_ptr cinfo, int Ncolors[]) select_ncolors (j_decompress_ptr cinfo, int Ncolors[])
/* Determine allocation of desired colors to components, */ /* Determine allocation of desired colors to components, */
/* and fill in Ncolors[] array to indicate choice. */ /* and fill in Ncolors[] array to indicate choice. */
@@ -193,7 +194,10 @@ select_ncolors (j_decompress_ptr cinfo, int Ncolors[])
int total_colors, iroot, i, j; int total_colors, iroot, i, j;
boolean changed; boolean changed;
long temp; 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. */ /* We can allocate at least the nc'th root of max_colors per component. */
/* Compute floor(nc'th root of max_colors). */ /* Compute floor(nc'th root of max_colors). */
@@ -241,7 +245,7 @@ select_ncolors (j_decompress_ptr cinfo, int Ncolors[])
} }
LOCAL int LOCAL(int)
output_value (j_decompress_ptr cinfo, int ci, int j, int maxj) output_value (j_decompress_ptr cinfo, int ci, int j, int maxj)
/* Return j'th output value, where j will range from 0 to maxj */ /* Return j'th output value, where j will range from 0 to maxj */
/* The output values must fall in 0..MAXJSAMPLE in increasing order */ /* The output values must fall in 0..MAXJSAMPLE in increasing order */
@@ -255,7 +259,7 @@ output_value (j_decompress_ptr cinfo, int ci, int j, int maxj)
} }
LOCAL int LOCAL(int)
largest_input_value (j_decompress_ptr cinfo, int ci, int j, int maxj) largest_input_value (j_decompress_ptr cinfo, int ci, int j, int maxj)
/* Return largest input value that should map to j'th output value */ /* Return largest input value that should map to j'th output value */
/* Must have largest(j=0) >= 0, and largest(j=maxj) >= MAXJSAMPLE */ /* Must have largest(j=0) >= 0, and largest(j=maxj) >= MAXJSAMPLE */
@@ -269,7 +273,7 @@ largest_input_value (j_decompress_ptr cinfo, int ci, int j, int maxj)
* Create the colormap. * Create the colormap.
*/ */
LOCAL void LOCAL(void)
create_colormap (j_decompress_ptr cinfo) create_colormap (j_decompress_ptr cinfo)
{ {
my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
@@ -329,7 +333,7 @@ create_colormap (j_decompress_ptr cinfo)
* Create the color index table. * Create the color index table.
*/ */
LOCAL void LOCAL(void)
create_colorindex (j_decompress_ptr cinfo) create_colorindex (j_decompress_ptr cinfo)
{ {
my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
@@ -392,7 +396,7 @@ create_colorindex (j_decompress_ptr cinfo)
* distinct output values. * distinct output values.
*/ */
LOCAL ODITHER_MATRIX_PTR LOCAL(ODITHER_MATRIX_PTR)
make_odither_array (j_decompress_ptr cinfo, int ncolors) make_odither_array (j_decompress_ptr cinfo, int ncolors)
{ {
ODITHER_MATRIX_PTR odither; ODITHER_MATRIX_PTR odither;
@@ -428,7 +432,7 @@ make_odither_array (j_decompress_ptr cinfo, int ncolors)
* share a dither table. * share a dither table.
*/ */
LOCAL void LOCAL(void)
create_odither_tables (j_decompress_ptr cinfo) create_odither_tables (j_decompress_ptr cinfo)
{ {
my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
@@ -455,7 +459,7 @@ create_odither_tables (j_decompress_ptr cinfo)
* Map some rows of pixels to the output colormapped representation. * Map some rows of pixels to the output colormapped representation.
*/ */
METHODDEF void METHODDEF(void)
color_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf, color_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
JSAMPARRAY output_buf, int num_rows) JSAMPARRAY output_buf, int num_rows)
/* General case, no dithering */ /* General case, no dithering */
@@ -483,7 +487,7 @@ color_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
} }
METHODDEF void METHODDEF(void)
color_quantize3 (j_decompress_ptr cinfo, JSAMPARRAY input_buf, color_quantize3 (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
JSAMPARRAY output_buf, int num_rows) JSAMPARRAY output_buf, int num_rows)
/* Fast path for out_color_components==3, no dithering */ /* Fast path for out_color_components==3, no dithering */
@@ -511,7 +515,7 @@ color_quantize3 (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
} }
METHODDEF void METHODDEF(void)
quantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, quantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
JSAMPARRAY output_buf, int num_rows) JSAMPARRAY output_buf, int num_rows)
/* General case, with ordered dithering */ /* General case, with ordered dithering */
@@ -561,7 +565,7 @@ quantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
} }
METHODDEF void METHODDEF(void)
quantize3_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, quantize3_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
JSAMPARRAY output_buf, int num_rows) JSAMPARRAY output_buf, int num_rows)
/* Fast path for out_color_components==3, with ordered dithering */ /* Fast path for out_color_components==3, with ordered dithering */
@@ -606,7 +610,7 @@ quantize3_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
} }
METHODDEF void METHODDEF(void)
quantize_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, quantize_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
JSAMPARRAY output_buf, int num_rows) JSAMPARRAY output_buf, int num_rows)
/* General case, with Floyd-Steinberg dithering */ /* General case, with Floyd-Steinberg dithering */
@@ -718,7 +722,7 @@ quantize_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
* Allocate workspace for Floyd-Steinberg errors. * Allocate workspace for Floyd-Steinberg errors.
*/ */
LOCAL void LOCAL(void)
alloc_fs_workspace (j_decompress_ptr cinfo) alloc_fs_workspace (j_decompress_ptr cinfo)
{ {
my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
@@ -737,7 +741,7 @@ alloc_fs_workspace (j_decompress_ptr cinfo)
* Initialize for one-pass color quantization. * Initialize for one-pass color quantization.
*/ */
METHODDEF void METHODDEF(void)
start_pass_1_quant (j_decompress_ptr cinfo, boolean is_pre_scan) start_pass_1_quant (j_decompress_ptr cinfo, boolean is_pre_scan)
{ {
my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
@@ -794,7 +798,7 @@ start_pass_1_quant (j_decompress_ptr cinfo, boolean is_pre_scan)
* Finish up at the end of the pass. * Finish up at the end of the pass.
*/ */
METHODDEF void METHODDEF(void)
finish_pass_1_quant (j_decompress_ptr cinfo) finish_pass_1_quant (j_decompress_ptr cinfo)
{ {
/* no work in 1-pass case */ /* no work in 1-pass case */
@@ -806,7 +810,7 @@ finish_pass_1_quant (j_decompress_ptr cinfo)
* Shouldn't get to this module! * Shouldn't get to this module!
*/ */
METHODDEF void METHODDEF(void)
new_color_map_1_quant (j_decompress_ptr cinfo) new_color_map_1_quant (j_decompress_ptr cinfo)
{ {
ERREXIT(cinfo, JERR_MODE_CHANGE); ERREXIT(cinfo, JERR_MODE_CHANGE);
@@ -817,7 +821,7 @@ new_color_map_1_quant (j_decompress_ptr cinfo)
* Module initialization routine for 1-pass color quantization. * Module initialization routine for 1-pass color quantization.
*/ */
GLOBAL void GLOBAL(void)
jinit_1pass_quantizer (j_decompress_ptr cinfo) jinit_1pass_quantizer (j_decompress_ptr cinfo)
{ {
my_cquantize_ptr cquantize; my_cquantize_ptr cquantize;

View File

@@ -1,7 +1,8 @@
/* /*
* jquant2.c * jquant2.c
* *
* Copyright (C) 1991-1995, Thomas G. Lane. * Copyright (C) 1991-1996, Thomas G. Lane.
* Copyright (C) 2009, D. R. Commander.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * 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 G_SCALE 3 /* scale G distances by this much */
#define B_SCALE 1 /* and B 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 static const int c_scales[3]={R_SCALE, G_SCALE, B_SCALE};
* in jmorecfg.h. As the code stands, it will do the right thing for R,G,B #define C0_SCALE c_scales[rgb_red[cinfo->out_color_space]]
* and B,G,R orders. If you define some other weird order in jmorecfg.h, #define C1_SCALE c_scales[rgb_green[cinfo->out_color_space]]
* you'll get compile errors until you extend this logic. In that case #define C2_SCALE c_scales[rgb_blue[cinfo->out_color_space]]
* 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
/* /*
* First we have the histogram data structure and routines for creating it. * First we have the histogram data structure and routines for creating it.
@@ -220,7 +202,7 @@ typedef my_cquantizer * my_cquantize_ptr;
* NULL pointer). * NULL pointer).
*/ */
METHODDEF void METHODDEF(void)
prescan_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf, prescan_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
JSAMPARRAY output_buf, int num_rows) JSAMPARRAY output_buf, int num_rows)
{ {
@@ -269,7 +251,7 @@ typedef struct {
typedef box * boxptr; typedef box * boxptr;
LOCAL boxptr LOCAL(boxptr)
find_biggest_color_pop (boxptr boxlist, int numboxes) find_biggest_color_pop (boxptr boxlist, int numboxes)
/* Find the splittable box with the largest color population */ /* Find the splittable box with the largest color population */
/* Returns NULL if no splittable boxes remain */ /* Returns NULL if no splittable boxes remain */
@@ -289,7 +271,7 @@ find_biggest_color_pop (boxptr boxlist, int numboxes)
} }
LOCAL boxptr LOCAL(boxptr)
find_biggest_volume (boxptr boxlist, int numboxes) find_biggest_volume (boxptr boxlist, int numboxes)
/* Find the splittable box with the largest (scaled) volume */ /* Find the splittable box with the largest (scaled) volume */
/* Returns NULL if no splittable boxes remain */ /* Returns NULL if no splittable boxes remain */
@@ -309,7 +291,7 @@ find_biggest_volume (boxptr boxlist, int numboxes)
} }
LOCAL void LOCAL(void)
update_box (j_decompress_ptr cinfo, boxptr boxp) update_box (j_decompress_ptr cinfo, boxptr boxp)
/* Shrink the min/max bounds of a box to enclose only nonzero elements, */ /* Shrink the min/max bounds of a box to enclose only nonzero elements, */
/* and recompute its volume and population */ /* and recompute its volume and population */
@@ -420,7 +402,7 @@ update_box (j_decompress_ptr cinfo, boxptr boxp)
} }
LOCAL int LOCAL(int)
median_cut (j_decompress_ptr cinfo, boxptr boxlist, int numboxes, median_cut (j_decompress_ptr cinfo, boxptr boxlist, int numboxes,
int desired_colors) int desired_colors)
/* Repeatedly select and split the largest box until we have enough boxes */ /* Repeatedly select and split the largest box until we have enough boxes */
@@ -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. /* 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. * This code does the right thing for R,G,B or B,G,R color orders only.
*/ */
#if RGB_RED == 0 if (rgb_red[cinfo->out_color_space] == 0) {
cmax = c1; n = 1; cmax = c1; n = 1;
if (c0 > cmax) { cmax = c0; n = 0; } if (c0 > cmax) { cmax = c0; n = 0; }
if (c2 > cmax) { n = 2; } if (c2 > cmax) { n = 2; }
#else }
cmax = c1; n = 1; else {
if (c2 > cmax) { cmax = c2; n = 2; } cmax = c1; n = 1;
if (c0 > cmax) { n = 0; } if (c2 > cmax) { cmax = c2; n = 2; }
#endif if (c0 > cmax) { n = 0; }
}
/* Choose split point along selected axis, and update box bounds. /* Choose split point along selected axis, and update box bounds.
* Current algorithm: split at halfway point. * Current algorithm: split at halfway point.
* (Since the box has been shrunk to minimum volume, * (Since the box has been shrunk to minimum volume,
@@ -495,7 +478,7 @@ median_cut (j_decompress_ptr cinfo, boxptr boxlist, int numboxes,
} }
LOCAL void LOCAL(void)
compute_color (j_decompress_ptr cinfo, boxptr boxp, int icolor) compute_color (j_decompress_ptr cinfo, boxptr boxp, int icolor)
/* Compute representative color for a box, put it in colormap[icolor] */ /* Compute representative color for a box, put it in colormap[icolor] */
{ {
@@ -535,7 +518,7 @@ compute_color (j_decompress_ptr cinfo, boxptr boxp, int icolor)
} }
LOCAL void LOCAL(void)
select_colors (j_decompress_ptr cinfo, int desired_colors) select_colors (j_decompress_ptr cinfo, int desired_colors)
/* Master routine for color selection */ /* Master routine for color selection */
{ {
@@ -642,7 +625,7 @@ select_colors (j_decompress_ptr cinfo, int desired_colors)
* inner-loop variables. * inner-loop variables.
*/ */
LOCAL int LOCAL(int)
find_nearby_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2, find_nearby_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
JSAMPLE colorlist[]) JSAMPLE colorlist[])
/* Locate the colormap entries close enough to an update box to be candidates /* Locate the colormap entries close enough to an update box to be candidates
@@ -771,7 +754,7 @@ find_nearby_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
} }
LOCAL void LOCAL(void)
find_best_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2, find_best_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
int numcolors, JSAMPLE colorlist[], JSAMPLE bestcolor[]) int numcolors, JSAMPLE colorlist[], JSAMPLE bestcolor[])
/* Find the closest colormap entry for each cell in the update box, /* Find the closest colormap entry for each cell in the update box,
@@ -851,7 +834,7 @@ find_best_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
} }
LOCAL void LOCAL(void)
fill_inverse_cmap (j_decompress_ptr cinfo, int c0, int c1, int c2) fill_inverse_cmap (j_decompress_ptr cinfo, int c0, int c1, int c2)
/* Fill the inverse-colormap entries in the update box that contains */ /* Fill the inverse-colormap entries in the update box that contains */
/* histogram cell c0/c1/c2. (Only that one cell MUST be filled, but */ /* histogram cell c0/c1/c2. (Only that one cell MUST be filled, but */
@@ -911,7 +894,7 @@ fill_inverse_cmap (j_decompress_ptr cinfo, int c0, int c1, int c2)
* Map some rows of pixels to the output colormapped representation. * Map some rows of pixels to the output colormapped representation.
*/ */
METHODDEF void METHODDEF(void)
pass2_no_dither (j_decompress_ptr cinfo, pass2_no_dither (j_decompress_ptr cinfo,
JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows) JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows)
/* This version performs no dithering */ /* This version performs no dithering */
@@ -945,7 +928,7 @@ pass2_no_dither (j_decompress_ptr cinfo,
} }
METHODDEF void METHODDEF(void)
pass2_fs_dither (j_decompress_ptr cinfo, pass2_fs_dither (j_decompress_ptr cinfo,
JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows) JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows)
/* This version performs Floyd-Steinberg dithering */ /* This version performs Floyd-Steinberg dithering */
@@ -1104,7 +1087,7 @@ pass2_fs_dither (j_decompress_ptr cinfo,
* to Aaron Giles for this idea. * to Aaron Giles for this idea.
*/ */
LOCAL void LOCAL(void)
init_error_limit (j_decompress_ptr cinfo) init_error_limit (j_decompress_ptr cinfo)
/* Allocate and fill in the error_limiter table */ /* Allocate and fill in the error_limiter table */
{ {
@@ -1139,7 +1122,7 @@ init_error_limit (j_decompress_ptr cinfo)
* Finish up at the end of each pass. * Finish up at the end of each pass.
*/ */
METHODDEF void METHODDEF(void)
finish_pass1 (j_decompress_ptr cinfo) finish_pass1 (j_decompress_ptr cinfo)
{ {
my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
@@ -1152,7 +1135,7 @@ finish_pass1 (j_decompress_ptr cinfo)
} }
METHODDEF void METHODDEF(void)
finish_pass2 (j_decompress_ptr cinfo) finish_pass2 (j_decompress_ptr cinfo)
{ {
/* no work */ /* no work */
@@ -1163,7 +1146,7 @@ finish_pass2 (j_decompress_ptr cinfo)
* Initialize for each processing pass. * Initialize for each processing pass.
*/ */
METHODDEF void METHODDEF(void)
start_pass_2_quant (j_decompress_ptr cinfo, boolean is_pre_scan) start_pass_2_quant (j_decompress_ptr cinfo, boolean is_pre_scan)
{ {
my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
@@ -1226,7 +1209,7 @@ start_pass_2_quant (j_decompress_ptr cinfo, boolean is_pre_scan)
* Switch to a new external colormap between output passes. * Switch to a new external colormap between output passes.
*/ */
METHODDEF void METHODDEF(void)
new_color_map_2_quant (j_decompress_ptr cinfo) new_color_map_2_quant (j_decompress_ptr cinfo)
{ {
my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
@@ -1240,7 +1223,7 @@ new_color_map_2_quant (j_decompress_ptr cinfo)
* Module initialization routine for 2-pass color quantization. * Module initialization routine for 2-pass color quantization.
*/ */
GLOBAL void GLOBAL(void)
jinit_2pass_quantizer (j_decompress_ptr cinfo) jinit_2pass_quantizer (j_decompress_ptr cinfo)
{ {
my_cquantize_ptr cquantize; my_cquantize_ptr cquantize;

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));

299
jsimd_none.c Normal file
View File

@@ -0,0 +1,299 @@
/*
* jsimd_none.c
*
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
* Copyright 2009 D. R. Commander
*
* Based on the x86 SIMD extension for IJG JPEG library,
* Copyright (C) 1999-2006, MIYASAKA Masaru.
*
* This file contains stubs for when there is no SIMD support available.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jsimd.h"
#include "jdct.h"
#include "jsimddct.h"
GLOBAL(int)
jsimd_can_rgb_ycc (void)
{
return 0;
}
GLOBAL(int)
jsimd_can_ycc_rgb (void)
{
return 0;
}
GLOBAL(void)
jsimd_rgb_ycc_convert (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
JDIMENSION output_row, int num_rows)
{
}
GLOBAL(void)
jsimd_ycc_rgb_convert (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION input_row,
JSAMPARRAY output_buf, int num_rows)
{
}
GLOBAL(int)
jsimd_can_h2v2_downsample (void)
{
return 0;
}
GLOBAL(int)
jsimd_can_h2v1_downsample (void)
{
return 0;
}
GLOBAL(void)
jsimd_h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY output_data)
{
}
GLOBAL(void)
jsimd_h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY output_data)
{
}
GLOBAL(int)
jsimd_can_h2v2_upsample (void)
{
return 0;
}
GLOBAL(int)
jsimd_can_h2v1_upsample (void)
{
return 0;
}
GLOBAL(void)
jsimd_h2v2_upsample (j_decompress_ptr cinfo,
jpeg_component_info * compptr,
JSAMPARRAY input_data,
JSAMPARRAY * output_data_ptr)
{
}
GLOBAL(void)
jsimd_h2v1_upsample (j_decompress_ptr cinfo,
jpeg_component_info * compptr,
JSAMPARRAY input_data,
JSAMPARRAY * output_data_ptr)
{
}
GLOBAL(int)
jsimd_can_h2v2_fancy_upsample (void)
{
return 0;
}
GLOBAL(int)
jsimd_can_h2v1_fancy_upsample (void)
{
return 0;
}
GLOBAL(void)
jsimd_h2v2_fancy_upsample (j_decompress_ptr cinfo,
jpeg_component_info * compptr,
JSAMPARRAY input_data,
JSAMPARRAY * output_data_ptr)
{
}
GLOBAL(void)
jsimd_h2v1_fancy_upsample (j_decompress_ptr cinfo,
jpeg_component_info * compptr,
JSAMPARRAY input_data,
JSAMPARRAY * output_data_ptr)
{
}
GLOBAL(int)
jsimd_can_h2v2_merged_upsample (void)
{
return 0;
}
GLOBAL(int)
jsimd_can_h2v1_merged_upsample (void)
{
return 0;
}
GLOBAL(void)
jsimd_h2v2_merged_upsample (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf,
JDIMENSION in_row_group_ctr,
JSAMPARRAY output_buf)
{
}
GLOBAL(void)
jsimd_h2v1_merged_upsample (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf,
JDIMENSION in_row_group_ctr,
JSAMPARRAY output_buf)
{
}
GLOBAL(int)
jsimd_can_convsamp (void)
{
return 0;
}
GLOBAL(int)
jsimd_can_convsamp_float (void)
{
return 0;
}
GLOBAL(void)
jsimd_convsamp (JSAMPARRAY sample_data, JDIMENSION start_col,
DCTELEM * workspace)
{
}
GLOBAL(void)
jsimd_convsamp_float (JSAMPARRAY sample_data, JDIMENSION start_col,
FAST_FLOAT * workspace)
{
}
GLOBAL(int)
jsimd_can_fdct_islow (void)
{
return 0;
}
GLOBAL(int)
jsimd_can_fdct_ifast (void)
{
return 0;
}
GLOBAL(int)
jsimd_can_fdct_float (void)
{
return 0;
}
GLOBAL(void)
jsimd_fdct_islow (DCTELEM * data)
{
}
GLOBAL(void)
jsimd_fdct_ifast (DCTELEM * data)
{
}
GLOBAL(void)
jsimd_fdct_float (FAST_FLOAT * data)
{
}
GLOBAL(int)
jsimd_can_quantize (void)
{
return 0;
}
GLOBAL(int)
jsimd_can_quantize_float (void)
{
return 0;
}
GLOBAL(void)
jsimd_quantize (JCOEFPTR coef_block, DCTELEM * divisors,
DCTELEM * workspace)
{
}
GLOBAL(void)
jsimd_quantize_float (JCOEFPTR coef_block, FAST_FLOAT * divisors,
FAST_FLOAT * workspace)
{
}
GLOBAL(int)
jsimd_can_idct_2x2 (void)
{
return 0;
}
GLOBAL(int)
jsimd_can_idct_4x4 (void)
{
return 0;
}
GLOBAL(void)
jsimd_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf,
JDIMENSION output_col)
{
}
GLOBAL(void)
jsimd_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf,
JDIMENSION output_col)
{
}
GLOBAL(int)
jsimd_can_idct_islow (void)
{
return 0;
}
GLOBAL(int)
jsimd_can_idct_ifast (void)
{
return 0;
}
GLOBAL(int)
jsimd_can_idct_float (void)
{
return 0;
}
GLOBAL(void)
jsimd_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf,
JDIMENSION output_col)
{
}
GLOBAL(void)
jsimd_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf,
JDIMENSION output_col)
{
}
GLOBAL(void)
jsimd_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf,
JDIMENSION output_col)
{
}

101
jsimddct.h Normal file
View File

@@ -0,0 +1,101 @@
/*
* jsimddct.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_convsamp jSCanConv
#define jsimd_can_convsamp_float jSCanConvF
#define jsimd_convsamp jSConv
#define jsimd_convsamp_float jSConvF
#define jsimd_can_fdct_islow jSCanFDCTIS
#define jsimd_can_fdct_ifast jSCanFDCTIF
#define jsimd_can_fdct_float jSCanFDCTFl
#define jsimd_fdct_islow jSFDCTIS
#define jsimd_fdct_ifast jSFDCTIF
#define jsimd_fdct_float jSFDCTFl
#define jsimd_can_quantize jSCanQuant
#define jsimd_can_quantize_float jSCanQuantF
#define jsimd_quantize jSQuant
#define jsimd_quantize_float jSQuantF
#define jsimd_can_idct_2x2 jSCanIDCT22
#define jsimd_can_idct_4x4 jSCanIDCT44
#define jsimd_idct_2x2 jSIDCT22
#define jsimd_idct_4x4 jSIDCT44
#define jsimd_can_idct_islow jSCanIDCTIS
#define jsimd_can_idct_ifast jSCanIDCTIF
#define jsimd_can_idct_float jSCanIDCTFl
#define jsimd_idct_islow jSIDCTIS
#define jsimd_idct_ifast jSIDCTIF
#define jsimd_idct_float jSIDCTFl
#endif /* NEED_SHORT_EXTERNAL_NAMES */
EXTERN(int) jsimd_can_convsamp JPP((void));
EXTERN(int) jsimd_can_convsamp_float JPP((void));
EXTERN(void) jsimd_convsamp JPP((JSAMPARRAY sample_data,
JDIMENSION start_col,
DCTELEM * workspace));
EXTERN(void) jsimd_convsamp_float JPP((JSAMPARRAY sample_data,
JDIMENSION start_col,
FAST_FLOAT * workspace));
EXTERN(int) jsimd_can_fdct_islow JPP((void));
EXTERN(int) jsimd_can_fdct_ifast JPP((void));
EXTERN(int) jsimd_can_fdct_float JPP((void));
EXTERN(void) jsimd_fdct_islow JPP((DCTELEM * data));
EXTERN(void) jsimd_fdct_ifast JPP((DCTELEM * data));
EXTERN(void) jsimd_fdct_float JPP((FAST_FLOAT * data));
EXTERN(int) jsimd_can_quantize JPP((void));
EXTERN(int) jsimd_can_quantize_float JPP((void));
EXTERN(void) jsimd_quantize JPP((JCOEFPTR coef_block,
DCTELEM * divisors,
DCTELEM * workspace));
EXTERN(void) jsimd_quantize_float JPP((JCOEFPTR coef_block,
FAST_FLOAT * divisors,
FAST_FLOAT * workspace));
EXTERN(int) jsimd_can_idct_2x2 JPP((void));
EXTERN(int) jsimd_can_idct_4x4 JPP((void));
EXTERN(void) jsimd_idct_2x2 JPP((j_decompress_ptr cinfo,
jpeg_component_info * compptr,
JCOEFPTR coef_block,
JSAMPARRAY output_buf,
JDIMENSION output_col));
EXTERN(void) jsimd_idct_4x4 JPP((j_decompress_ptr cinfo,
jpeg_component_info * compptr,
JCOEFPTR coef_block,
JSAMPARRAY output_buf,
JDIMENSION output_col));
EXTERN(int) jsimd_can_idct_islow JPP((void));
EXTERN(int) jsimd_can_idct_ifast JPP((void));
EXTERN(int) jsimd_can_idct_float JPP((void));
EXTERN(void) jsimd_idct_islow JPP((j_decompress_ptr cinfo,
jpeg_component_info * compptr,
JCOEFPTR coef_block,
JSAMPARRAY output_buf,
JDIMENSION output_col));
EXTERN(void) jsimd_idct_ifast JPP((j_decompress_ptr cinfo,
jpeg_component_info * compptr,
JCOEFPTR coef_block,
JSAMPARRAY output_buf,
JDIMENSION output_col));
EXTERN(void) jsimd_idct_float JPP((j_decompress_ptr cinfo,
jpeg_component_info * compptr,
JCOEFPTR coef_block,
JSAMPARRAY output_buf,
JDIMENSION output_col));

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