Compare commits

...

1147 Commits

Author SHA1 Message Date
Kornel
0826579077 Fix PNG detection in CMake 2025-06-23 18:05:19 +01:00
Kornel
9b8d11f05e Fix -revert in tests 2025-01-04 02:11:32 +00:00
Kornel
1d3b119320 Fix djpeg tests 2025-01-04 00:52:39 +00:00
Kornel
38869c2d5d Use BUILD_SHARED_LIBS in cmake 2025-01-04 00:48:50 +00:00
Attila Repka
b6e0d504f7 fix(build): link to libmath on unix 2025-01-04 00:38:01 +00:00
Brendan Polin
3611168b5a Update BUILDING.md
Edited the vcpkg instructions for windows so they just work if you copy and paste
2025-01-04 00:37:38 +00:00
Kornel
97e2e1df43 Allow disabling fopen in SIMD 2025-01-03 10:04:01 +00:00
Kornel
ed667d4bfd Merge remote-tracking branch 'libjpeg-turbo/3.0.x' into mozjpeg
* libjpeg-turbo/3.0.x: (135 commits)
  Ensure methods called by global funcs are init'd
  Build: Generate 32-bit supplementary ppc64 .deb
  Build: Fix float test errors with Xcode 14.2/Arm
  AltiVec: Disable/Fix some strict compiler warnings
  Neon: Disable some strict compiler warnings
  Build: Make Mac packaging architecture-agnostic
  Exclude more code if !(C|D)_LOSSLESS_SUPPORTED
  Fix OSS-Fuzz decompress_yuv fuzzer MSan failure
  TJ doc: Density params require YCbCr or grayscale
  Allow disabling prog/opt/lossless if prev. enabled
  GitHub: Use macos-13 runner image w/ Xcode 14.2
  LICENSE.md: Update copyright year
  ChangeLog: Document accidental fix from 9983840e
  tj3Set(): Allow TJPARAM_LOSSLESSPT vals from 0..15
  Build: Support LLVM/Windows
  tj3Transform: Don't calc dst subsamp unless needed
  Fuzz: Calc. xformed buf size based on dst. subsamp
  TJ: Calc. xformed buf sizes based on dst. subsamp
  Minor TurboJPEG doc tweaks
  turbojpeg.c: Fix -Wsign-compare compiler warning
  ...
2025-01-03 09:57:35 +00:00
Kornel
c6d33b6d69 Merge commit '15274b901acb75d6d2433e8578f3cfbc6f4f5fd9' into mozjpeg
* commit '15274b901acb75d6d2433e8578f3cfbc6f4f5fd9': (98 commits)
  AppVeyor: Use SignPath release cert/only sign tags
  xform fuzz: Use only xform opts to set entropy alg
  jchuff.c: Test for out-of-range coefficients
  turbojpeg.h: Make customFilter() proto match doc
  ChangeLog.md: Fix typo
  djpeg: Fix -map option with 12-bit data precision
  Disallow color quantization with lossless decomp
  tj3Transform: Calc dst buf size from xformed dims
  README.md: Include link to project home page
  AppVeyor: Only add installers to zip file
  AppVeyor: Integrate with SignPath.io
  Fix build warnings/errs w/ -DNO_GETENV/-DNO_PUTENV
  GitHub: Fix x32 build
  Bump version to 3.0.0
  tjexample.c: Prevent integer overflow
  Disallow merged upsampling with lossless decomp
  SECURITY.md: Wordsmithing and clarifications
  GitHub: Add security policy
  ChangeLog.md: List CVE ID fixed by 9f756bc6
  jpeg_crop_scanline: Fix calc w/sclg + 2x4,4x2 samp
  ...
2024-12-23 01:25:43 +00:00
Kornel
15274b901a Merge tag '3.0.0' into '2.1.5.1'
# By DRC (96) and others
# Via DRC
* tag '3.0.0': (98 commits)
  AppVeyor: Use SignPath release cert/only sign tags
  xform fuzz: Use only xform opts to set entropy alg
  jchuff.c: Test for out-of-range coefficients
  turbojpeg.h: Make customFilter() proto match doc
  ChangeLog.md: Fix typo
  djpeg: Fix -map option with 12-bit data precision
  Disallow color quantization with lossless decomp
  tj3Transform: Calc dst buf size from xformed dims
  README.md: Include link to project home page
  AppVeyor: Only add installers to zip file
  AppVeyor: Integrate with SignPath.io
  Fix build warnings/errs w/ -DNO_GETENV/-DNO_PUTENV
  GitHub: Fix x32 build
  Bump version to 3.0.0
  tjexample.c: Prevent integer overflow
  Disallow merged upsampling with lossless decomp
  SECURITY.md: Wordsmithing and clarifications
  GitHub: Add security policy
  ChangeLog.md: List CVE ID fixed by 9f756bc6
  jpeg_crop_scanline: Fix calc w/sclg + 2x4,4x2 samp
  ...

# Conflicts:
#	CMakeLists.txt
#	ChangeLog.md
#	fuzz/decompress.cc
#	fuzz/decompress_yuv.cc
2024-12-23 00:23:06 +00:00
Kornel
d04cff3d6c Normalize whitespace and other merge details 2024-12-23 00:18:20 +00:00
DRC
e81cb16e0f Ensure methods called by global funcs are init'd
If a hypothetical calling application does something really stupid and
changes cinfo->data_precision after calling jpeg_start_*compress(), then
the precision-specific methods called by jpeg_write_scanlines(),
jpeg_write_raw_data(), jpeg_finish_compress(), jpeg_read_scanlines(),
jpeg_read_raw_data(), or jpeg_start_output() may not be initialized.

Ensure that the first precision-specific method (which will always be
cinfo->main->process_data*(), cinfo->coef->compress_data*(), or
cinfo->coef->decompress_data()) called by any global function that may
be called after jpeg_start_*compress() is initialized and non-NULL.
This increases the likelihood (but does not guarantee) that a
hypothetical stupid calling application will fail gracefully rather than
segfault if it changes cinfo->data_precision after calling
jpeg_start_*compress().  A hypothetical stupid calling application can
still bork itself by changing cinfo->data_precision after initializing
the source manager but before calling jpeg_start_compress(), or after
initializing the destination manager but before calling
jpeg_start_decompress().
2024-12-18 16:37:02 -05:00
DRC
3e703af408 Build: Generate 32-bit supplementary ppc64 .deb
As with x86-64, the Power ISA basically implements 64-bit instructions
as extensions of their 32-bit counterparts.  Thus, 64-bit Power ISA CPUs
can natively execute legacy 32-bit PowerPC instructions when running in
big-endian mode.  Most Power ISA support has shifted (pun intended) to
little-endian mode, so there are few remaining operating systems that
support big-endian mode.  Debian is one of them, however (albeit
unofficially.)
2024-12-18 10:15:24 -05:00
DRC
b4ca1ba192 Build: Fix float test errors with Xcode 14.2/Arm
Unlike other versions of Clang 14.0.0, AppleClang 14.0.0 in Xcode 14.2
retains the old -ffp-contract=off default.  Apple didn't adopt
-ffp-contract=on as the default until Xcode 14.3 (AppleClang 14.0.3.)
This has been confirmed in the Xcode 14.3 release notes.
2024-12-12 16:02:05 -05:00
DRC
1c864a9d15 AltiVec: Disable/Fix some strict compiler warnings
We use a standard set of strict compiler warnings with Clang and GCC to
continuously test and maintain C89 conformance in the libjpeg API code.
However, SIMD extensions need not comply with that.  The AltiVec code
specifically uses some C99isms, so disable -Wc99-extensions and
-Wpedantic in the scope of that code.  Also disable -Wshadow, because
I'm too lazy to fix the TRANSPOSE() macro.  Also
use #ifdef __BIG_ENDIAN__ and #if defined(__BIG_ENDIAN__) instead
of #if __BIG_ENDIAN__
2024-12-12 10:48:26 -05:00
DRC
ab56b9841c Neon: Disable some strict compiler warnings
We use a standard set of strict compiler warnings with Clang and GCC to
continuously test and maintain C89 conformance in the libjpeg API code.
However, SIMD extensions need not comply with that.  The Neon code
specifically uses some C99isms, so disable
-Wdeclaration-after-statement, -Wc99-extensions, and -Wpedantic in the
scope of that code.  Also modify the Neon feature tests so that they
will succeed if any of the aforementioned compiler warnings are enabled.
2024-12-11 17:19:02 -05:00
DRC
f23981b0aa Build: Make Mac packaging architecture-agnostic
Rename the ARMV8_BUILD CMake variable to SECONDARY_BUILD, and modify the
makemacpkg script so that it allows any architecture in a primary or
secondary build.  The idea is that Apple Silicon users can package an
arm64 primary build and a secondary x86_64 build, and Intel users can
package an x86_64 primary build and a secondary arm64 build, using the
same procedure.

Also simplify the iOS build instructions, using the
CMAKE_OSX_ARCHITECTURES variable rather than a toolchain.
2024-12-11 17:19:01 -05:00
DRC
3358df7da4 Exclude more code if !(C|D)_LOSSLESS_SUPPORTED 2024-11-18 16:20:00 -05:00
DRC
4e55d44658 Fix OSS-Fuzz decompress_yuv fuzzer MSan failure 2024-11-15 08:32:08 -05:00
DRC
3be781679c TJ doc: Density params require YCbCr or grayscale
Since libjpeg-turbo does not support Exif, the only way it can embed
density information in a JPEG image is by using the JFIF marker, which
is only written if the JPEG colorspace is YCbCr or grayscale.
(Referring to the conversation under #793, we may need to further
restrict that to 8-bit-per-sample JPEG images, because the JFIF spec
requires 8-bit data precision.)
2024-10-30 12:27:02 -04:00
DRC
45fa88190f Allow disabling prog/opt/lossless if prev. enabled
- Due to an oversight, a113506d17
  (libjpeg-turbo 1.4 beta1) effectively made the call to
  std_huff_tables() in jpeg_set_defaults() a no-op if the Huffman tables
  were previously defined, which made it impossible to disable Huffman
  table optimization or progressive mode if they were previously enabled
  in the same API instance.  std_huff_tables() retains its previous
  behavior for decompression instances, but it now force-enables the
  standard (baseline) Huffman tables for compression instances.

- Due to another oversight, there was no way to disable lossless mode
  if it was previously enabled in a particular API instance.
  jpeg_set_defaults() now accomplishes this, which makes
  TJ*PARAM_LOSSLESS behave as intended/documented.

- Due to yet another oversight, setCompDefaults() in the TurboJPEG API
  library permanently modified the value of TJ*PARAM_SUBSAMP when
  generating a lossless JPEG image, which affected subsequent lossy
  compression operations.  This issue was hidden by the issue above and
  thus does not need to be publicly documented.

Fixes #792
2024-10-24 19:06:02 -04:00
DRC
00e71d4c07 GitHub: Use macos-13 runner image w/ Xcode 14.2
(macos-12 is deprecated.)
2024-10-23 18:06:42 -04:00
DRC
b20e7f17dd LICENSE.md: Update copyright year 2024-09-24 10:46:56 -04:00
DRC
60a75c8a47 ChangeLog: Document accidental fix from 9983840e
Closes #789
2024-09-23 15:50:04 -04:00
DRC
63f4cf4222 tj3Set(): Allow TJPARAM_LOSSLESSPT vals from 0..15
The target data precision isn't known at the time that the calling
program sets TJPARAM_LOSSLESSPT, so tj3Set() needs to allow all possible
values (from 0 to 15.)  jpeg_enable_lossless(), which is called within
the body of tj3Compress*(), will throw an error if the point transform
value is greater than {data precision} - 1.
2024-09-23 13:31:20 -04:00
DRC
7f200a2acc Build: Support LLVM/Windows
Since LLVM/Windows emulates Visual Studio, CMake sets
CMAKE_C_SIMULATE_ID="MSVC" but does not set MSVC.  Thus, our build
system needs to enable most (but not all) of the Visual Studio features
when CMAKE_C_SIMLUATE_ID="MSVC".  Support for LLVM/Windows is currently
undocumented because it isn't a standalone build environment.  (It
requires the Visual Studio and Windows SDK headers and link libraries.)

Closes #786
2024-09-16 14:20:46 -04:00
DRC
f29eda6485 tj3Transform: Don't calc dst subsamp unless needed
This just improves code readability by emphasizing that we don't care
about the destination image's level of subsampling unless
TJPARAM_NOREALLOC is set or lossless cropping will be performed.
2024-09-14 11:10:59 -04:00
DRC
bcbca8b9bc Fuzz: Calc. xformed buf size based on dst. subsamp
(oversight from b3f0abe377)
2024-09-12 21:07:51 -04:00
DRC
b3f0abe377 TJ: Calc. xformed buf sizes based on dst. subsamp
With respect to tj3Transform(), this addresses an oversight from
bb1d540a80.

Note to self: A convenience function/method for computing the worst-case
transformed JPEG size for a particular transform would be nice.
2024-09-06 19:04:28 -04:00
DRC
6d9591703f Minor TurboJPEG doc tweaks
- When transforming, the worst-case JPEG buffer size depends on the
  subsampling level used in the destination image, since a grayscale
  transform might have been applied.

- Parentheses Police
2024-09-05 22:31:40 -04:00
DRC
2e40a6875d turbojpeg.c: Fix -Wsign-compare compiler warning
(introduced by previous commit)
2024-09-05 16:49:44 -04:00
DRC
758e8a8e9f Java: Use Java-style method nomenclature
:: is a C++ thing.
2024-09-05 14:57:15 -04:00
DRC
fe1e555a73 tjbenchtest.in: Grammar Police 2024-09-05 14:46:04 -04:00
DRC
bb1d540a80 TJ: Explicitly reject OOB lossless crop regions
tj*Transform() relied upon the underlying transupp API to check the
cropping region.  However, transupp uses unsigned integers for the
cropping region, whereas the tjregion structure uses signed integers.
Thus, casting negative values from a tjregion structure produced very
large unsigned values.  In the case of the left and upper boundary, this
was innocuous, because jtransform_request_workspace() rejected the
values as being out of bounds.  However, jtransform_request_workspace()
did not always reject very large width and height values, because it
supports expanding the destination image by specifying a cropping region
larger than the source image.  In certain cases, it allowed those
values, and the libjpeg memory manager subsequently ran out of memory.

NOTE: Prior to this commit, image expansion technically worked with
tj*Transform() as long as the cropping width and height were valid and
automatic JPEG buffer (re)allocation was used.  However, that behavior
is not a documented feature of the TurboJPEG API, nor do we have any way
of testing it at the moment.  Official support for image expansion can
be added later, if there is sufficient demand for it.

Similarly, this commit modifies tj3SetCroppingRegion() so that it
explicitly checks for left boundary values exactly equal to the scaled
image width and upper boundary values exactly equal to the scaled image
height.  If the specified cropping width or height was 0 (which is
interpreted as {scaled image width} - {left boundary} or
{scaled image height} - {upper boundary}), then such values caused a
cropping width or height of 0 to be passed to the libjpeg API.  In the
case of the width, this was innocuous, because jpeg_crop_scanline()
rejected the value.  In the case of the height, however, this caused
unexpected and hard-to-diagnose errors farther down the pipeline.
2024-09-05 14:37:12 -04:00
DRC
dd8b15ee82 tjbenchtest.in: Formatting tweak
(oversight from a5689cd45b)
2024-09-04 07:52:51 -04:00
DRC
e7e9344db1 TJ: Honor TJ*OPT_COPYNONE for individual xforms
jcopy_markers_execute() has historically ignored its option argument,
which is OK for jpegtran, but tj*Transform() needs to be able to save a
set of markers from the source image and write a subset of those markers
to each destination image.  Without that ability, the function
effectively behaved as if TJ*OPT_COPYNONE was not specified unless all
transforms specified it.
2024-09-04 07:34:42 -04:00
DRC
5550c80fdc Doc: "compress operation"="compression operation"
(consistification)
2024-09-03 17:20:10 -04:00
DRC
939f3814ab Test: Replace test2.icc with test3.icc
test3.icc is smaller, and it is also an RGB profile rather than a CMYK
profile.  (test1.icc is a CMYK profile.)
2024-09-03 15:47:57 -04:00
DRC
a5689cd45b Test: Replace big_tree8.bmp and big_building16.ppm
These images were only used with tjbenchtest and tjexampletest, but I
was concerned about introducing additional licensing provisions into the
libjpeg-turbo source tree.  Thus, this commit replaces them with images
that I own and can thus make available under the libjpeg-turbo licenses
with no additional provisions.
2024-09-03 15:47:37 -04:00
DRC
f5f8f5aadc TJ: Reorder functions to improve readability
Put all general functions at the top of the list, and ensure that all
functions are defined before they are mentioned.  Also consistify the
function ordering between turbojpeg.h and turbojpeg.c
2024-09-03 09:02:55 -04:00
DRC
843d04d9d4 CI: Run regression tests in parallel 2024-09-01 11:52:01 -04:00
DRC
797c6ccd98 Doc: Further clarify MCU definition 2024-09-01 11:25:29 -04:00
DRC
7ec70ee891 testclean.cmake: Remove croptest.log 2024-09-01 09:59:10 -04:00
DRC
174672af4e jquant1.c: Formatting tweak
Extending the Bayer matrix past Column 80 seems like a lesser
readability sin than not putting a space after each comma, especially
since we had to explicitly whitelist the file in checkstyle.
2024-09-01 09:55:52 -04:00
DRC
eb75363004 Update URLs
- Eliminate unnecessary "www."
- Use HTTPS.
- Update Java, MSYS, tdm-gcc, and NSIS URLs.
- Update URL and title of Agner Fog's assembly language optimization
  manual.
- Remove extraneous information about MASM and Borland Turbo Assembler
  and outdated NASM URLs from the x86 assembly headers, and mention
  Yasm.
2024-08-31 16:50:08 -04:00
DRC
0fb8fbe158 CMakeLists.txt: libjpeg-turbo "2.2.x" = "3.0.x" 2024-08-31 15:39:34 -04:00
DRC
8d76e4e550 Doc: "EXIF" = "Exif" 2024-08-31 15:33:55 -04:00
DRC
9983840eb6 TJ/xform: Check crop region against dest. image
Lossless cropping is performed after other lossless transform
operations, so the cropping region must be specified relative to the
destination image dimensions and level of chrominance subsampling, not
the source image dimensions and level of chrominance subsampling.

More specifically, if the lossless transform operation swaps the X and Y
axes, or if the image is converted to grayscale, then that changes the
cropping region requirements.
2024-08-31 15:04:30 -04:00
DRC
8456d2b98c Doc: "MCU block" = "iMCU" or "MCU"
The JPEG-1 spec never uses the term "MCU block".  That term is rarely
used in other literature to describe the equivalent of an MCU in an
interleaved JPEG image, but the libjpeg documentation uses "iMCU" to
describe the same thing.  "iMCU" is a better term, since the equivalent
of an interleaved MCU can contain multiple DCT blocks (or samples in
lossless mode) that are only grouped together if the image is
interleaved.

In the case of restart markers, "MCU block" was used in the libjpeg
documentation instead of "MCU", but "MCU" is more accurate and less
confusing.  (The restart interval is literally in MCUs, where one MCU
is one data unit in a non-interleaved JPEG image and multiple data units
in a multi-component interleaved JPEG image.)

In the case of 9b704f96b2, the issue was
actually with progressive JPEG images exactly two DCT blocks wide, not
two MCU blocks wide.

This commit also defines "MCU" and "MCU row" in the description of the
various restart marker options/parameters.  Although an MCU row is
technically always a row of samples in lossless mode, "sample row" was
confusing, since it is used in other places to describe a row of samples
for a single component (whereas an MCU row in a typical lossless JPEG
image consists of a row of interleaved samples for all components.)
2024-08-30 14:16:09 -04:00
DRC
5cf7960678 Undocument TJ*PARAM_RESTARTBLOCKS for lossless
TJ*PARAM_RESTARTBLOCKS technically works with lossless compression, but
it is not useful, since the value must be equal to the number of samples
in a row.  (In other words, it is no different than
TJ*PARAM_RESTARTINROWS, except that it requires the user to do more
math.)
2024-08-28 18:36:37 -04:00
DRC
d62079717c TJBench: Don't override subsamp until args parsed
Otherwise, passing -subsamp after -lossless might cause the worst-case
JPEG buffer size to be too small.
2024-08-28 18:21:55 -04:00
DRC
c72bbd9c06 tjbench.c: (Re)allow unreduced scaling factors
For reasons I can't recall, fc01f4673b
(the TurboJPEG 3 API overhaul) changed the C version of TJBench, but not
the Java version, so that it requires an exact scaling factor match (as
opposed to allowing unreduced scaling factors, as djpeg does and prior
versions of TJBench did.)  That might have been temporary testing code
that was accidentally committed.
2024-08-26 18:14:12 -04:00
DRC
35199878f6 TurboJPEG doc: Fix incorrect/confusing parentheses 2024-08-26 16:35:30 -04:00
DRC
00a261c473 tjbench.c: Code formatting tweak 2024-08-26 16:31:02 -04:00
DRC
4851cbe406 djpeg/jpeg_crop_scanline(): Disallow crop vals < 0
Because the crop spec was parsed using unsigned 32-bit integers,
negative numbers were interpreted as values ~= UINT_MAX (4,294,967,295).
This had the following ramifications:

- If the cropping region width was negative and the adjusted width + the
  adjusted left boundary was greater than 0, then the 32-bit unsigned
  integer bounds checks in djpeg and jpeg_crop_scanline() overflowed and
  failed to detect the out-of-bounds width, jpeg_crop_scanline() set
  cinfo->output_width to a value ~= UINT_MAX, and a buffer overrun and
  subsequent segfault occurred in the upsampling or color conversion
  routine.  The segfault occurred in the body of
  jpeg_skip_scanlines() --> read_and_discard_scanlines() if the cropping
  region upper boundary was greater than 0 and the JPEG image used
  chrominance subsampling and in the body of jpeg_read_scanlines()
  otherwise.

- If the cropping region width was negative and the adjusted width + the
  adjusted left boundary was 0, then a zero-width output image was
  generated.

- If the cropping region left boundary was negative, then an output
  image with bogus data was generated.

This commit modifies djpeg and jpeg_crop_scanline() so that the
aforementioned bounds checks use 64-bit unsigned integers, thus guarding
against overflow.  It similarly modifies jpeg_skip_scanlines().  In the
case of jpeg_skip_scanlines(), the issue was not reproducible with
djpeg, but passing a negative number of lines to jpeg_skip_scanlines()
caused a similar overflow if the number of lines +
cinfo->output_scanline was greater than 0.  That caused
jpeg_skip_scanlines() to read past the end of the JPEG image, throw a
warning ("Corrupt JPEG data: premature end of data segment"), and fail
to return unless warnings were treated as fatal.  Also, djpeg now parses
the crop spec using signed integers and checks for negative values.
2024-08-26 16:24:33 -04:00
DRC
548f732432 TJBench: Usage screen tweak
Indicate that -maxmemory and -maxpixels take an integer argument.
2024-08-26 10:14:11 -04:00
DRC
de4bbac55e TJCompressor.compress(): Fix lossls buf size calc 2024-08-23 12:48:34 -04:00
DRC
0acb084464 JNI: Fix *Image() array size issues w/ align != 1
+ check for mismatch between C and Java APIs in *saveImage().
2024-08-22 16:58:50 -04:00
DRC
d44fc54f94 Java: Unset srcBuf12/16 with BufferedImage/YUV src
Due to an oversight in the multi-precision feature,
TJCompressor.srcBuf12 and TJCompressor.srcBuf16 were not set to null
in TJCompressor.setSourceImage(YUVImage) or
TJCompressor.setSourceImage(BufferedImage, ...).  Thus, if an
application set a 12-bit or 16-bit packed-pixel buffer as the source
image then set a BufferedImage with integer pixels as the source image,
TJCompress.compress() would compress from the 12-bit or 16-bit
packed-pixel buffer instead of the BufferedImage.  The odds of an
application actually doing that are very slim, however.
2024-08-21 16:44:46 -04:00
DRC
8c2e7306cf Java doc: Minor formatting tweak 2024-08-21 13:03:41 -04:00
DRC
49f1b5807d TJBench.java: Explicitly set restartIntervalBlocks
This is just a readability thing.  Java initializes integer fields to 0
by default.
2024-08-20 15:11:20 -04:00
DRC
a9723f8a98 cjpeg/djpeg/jpegtran: Restore jpeg-6b arg abbrevs
There are two approaches to handling abbreviated command-line options:

1. If a new option is introduced that begins with the same letters as an
existing option, require a longer abbreviation for the existing option
in order to ensure that abbreviations are always unique.

2. Require a unique abbreviation only for new options, and match all
non-unique abbreviations with existing options, thus maintaining
backward compatibility.

keymatch() supports either approach, and Tom Lane historically seemed to
prefer Approach 2, whereas both approaches have been applied
inconsistently in the years since.  This commit consistently applies
Approach 2.

More specific notes:

We unnecessarily required 'cjpeg -progressive' to be abbreviated as
'cjpeg -pro' rather than 'cjpeg -p' when the -precision option was
introduced in libjpeg-turbo 3.0 beta.

The IJG unnecessarily required 'cjpeg -scans' to be abbreviated as
'cjpeg -scan' rather than 'cjpeg -sc' when the -scale option was
introduced in jpeg-7.  We even more unnecessarily adopted that
requirement, even though we never adopted the -scale option.

We unnecessarily required 'djpeg -scale' to be abbreviated as
'djpeg -sc' rather than 'djpeg -s' when the -skip option was introduced
in libjpeg-turbo 1.5 beta.

The IJG unnecessarily required 'jpegtran -copy' to be abbreviated as
'jpegtran -co' rather than 'jpegtran -c' when the -crop option was
introduced in jpeg-7.

The IJG unnecessarily required 'jpegtran -progressive' to be abbreviated
as 'jpegtran -pr' rather than 'jpegtran -p' when the -perfect option was
introduced in jpeg-7.
2024-08-19 17:12:33 -04:00
DRC
562ad7612e OSS-Fuzz: More MSan fixes
We need to use tj3Alloc() (which, when ZERO_BUFFERS is defined, calls
calloc() instead of malloc()) to allocate all destination buffers.
Otherwise, if the compression/decompression/transform operation fails,
then the buffer checksum (which is computed to prevent the compiler from
optimizing out the whole test, since the destination buffer is never
used otherwise) will depend upon values in the destination buffer that
were never written, and MSan will complain.
2024-08-19 10:06:59 -04:00
DRC
488d42a8a5 OSS-Fuzz: Define ZERO_BUFFERS for MSan build
... and use tj3Alloc() to allocate compression/transformation
destination buffers.
2024-08-16 12:17:17 -04:00
DRC
0c23b0ad60 Various doc tweaks
- "Optimized baseline entropy coding" = "Huffman table optimization"

  "Optimized baseline entropy coding" was meant to emphasize that the
  feature is only useful when generating baseline (single-scan lossy
  8-bit-per-sample Huffman-coded) JPEG images, because it is
  automatically enabled when generating Huffman-coded progressive
  (multi-scan), 12-bit-per-sample, and lossless JPEG images.  However,
  Huffman table optimization isn't actually an integral part of those
  non-baseline modes.  You can forego Huffman table optimization with
  12-bit data precision if you supply your own Huffman tables.  The spec
  doesn't require it with progressive or lossless mode, either, although
  our implementation does.  Furthermore, "baseline" describes more than
  just the type of entropy coding used.  It was incorrect to say that
  optimized "baseline" entropy coding is automatically enabled for
  Huffman-coded progressive, 12-bit-per-sample, and lossless JPEG
  images, since those are clearly not baseline images.

- "Progressive entropy coding" = "Progressive JPEG"

  "Progressive" describes more than just the type of entropy coding
  used.  (In fact, both Huffman-coded and arithmetic-coded images can be
  progressive.)

- Mention that TJPARAM_OPTIMIZE/TJ.PARAM_OPTIMIZE can be used with
  lossless transformation as well.

- General wordsmithing

- Formatting tweaks
2024-08-16 11:49:00 -04:00
DRC
b4336c3afb Work around valgrind/MSan SIMD false positives
Referring to
https://sourceforge.net/p/libjpeg-turbo/bugs/48,
https://sourceforge.net/p/libjpeg-turbo/bugs/82,
 #15, #238, #253, and #619,
valgrind and MSan have failed to properly detect data initialization by
libjpeg-turbo's x86 SIMD extensions for the entire 14 years that
libjpeg-turbo has been a project, resulting in false positives unless
libjpeg-turbo is built with WITH_SIMD=0 or run with JSIMD_FORCENONE=1.
This commit introduces a new C preprocessor macro (ZERO_BUFFERS) that,
if set, causes libjpeg-turbo to zero certain buffers in order to work
around the specific valgrind/MSan test failures caused by the
aforementioned false positives.  This allows us to more closely
approximate the production configuration of libjpeg-turbo when testing
with valgrind or MSan.

Closes #781
2024-08-13 16:23:40 -04:00
DRC
8db0312668 example.c: Write correct dimensions to PPM header
The dimensions in the PPM header of the output file generated by
'example decompress' were always 640 x 480, regardless of the size of
the JPEG image being decompressed.  Our regression tests (which this
commit also fixes) missed the bug because they decompressed the
640 x 480 image generated by 'example compress'.

Fixes #778
2024-08-02 09:06:40 -04:00
DRC
0566d51e09 GitHub Actions: Specify Monterey for macOS build
The Big Sur hosted runner is no longer available.
2024-07-09 17:18:53 -04:00
DRC
e287a35762 Build: Put gastest.o in ${CMAKE_BINARY_DIR}/simd
Closes #776
2024-07-04 10:03:50 -04:00
DRC
51d021bf01 TurboJPEG: Fix 12-bit-per-sample arith-coded compr
(Regression introduced by 7bb958b732)

Because of 7bb958b732, the TurboJPEG
compression and encoding functions no longer transfer the value of
TJPARAM_OPTIMIZE into cinfo->data_precision unless the data precision
is 8.  The intent of that was to prevent using_std_huff_tables() from
being called more than once when reusing the same compressor object to
generate multiple 12-bit-per-sample JPEG images.  However, because
cinfo->optimize_coding is always set to TRUE by jpeg_set_defaults() if
the data precision is 12, calling applications that use 12-bit data
precision had to unset cinfo->optimize_coding if they set
cinfo->arith_code after calling jpeg_set_defaults().  Because of
7bb958b732, the TurboJPEG API stopped
doing that except with 8-bit data precision.  Thus, attempting to
generate a 12-bit-per-sample arithmetic-coded lossy JPEG image using
the TurboJPEG API failed with "Requested features are incompatible."

Since the compressor will always fail if cinfo->arith_code and
cinfo->optimize_coding are both set, and since cinfo->optimize_coding
has no relevance for arithmetic coding, the most robust and user-proof
solution is for jinit_c_master_control() to set cinfo->optimize_coding
to FALSE if cinfo->arith_code is TRUE.

This commit also:
- modifies TJBench so that it no longer reports that it is using
  optimized baseline entropy coding in modes where that setting
  is irrelevant,
- amends the cjpeg documentation to clarify that -optimize is implied
  when specifying -progressive or '-precision 12' without -arithmetic,
  and
- prevents jpeg_set_defaults() from uselessly checking the value of
  cinfo->arith_code immediately after it has been set to FALSE.
2024-06-24 22:15:55 -04:00
DRC
bb3ab53157 cjpeg: Don't enable lossless until precision known
jpeg_enable_lossless() checks the point transform value against the data
precision, so we need to defer calling jpeg_enable_lossless() until
after all command-line options have been parsed.
2024-06-24 22:15:55 -04:00
DRC
a8aaaf5d5b cjpeg -verbose: Print PBMPLUS input file precision
This gives the user a hint as to whether converting the input file into
a JPEG file with a particular data precision will result in a loss of
precision.  Also modify usage.txt and the cjpeg man page to warn the
user about that possibility.
2024-06-24 22:15:55 -04:00
DRC
94c64ead85 Various doc tweaks
- "bits per component" = "bits per sample"

  Describing the data precision of a JPEG image using "bits per
  component" is technically correct, but "bits per sample" is the
  terminology that the JPEG-1 spec uses.  Also, "bits per component" is
  more commonly used to describe the precision of packed-pixel formats
  (as opposed to "bits per pixel") rather than planar formats, in which
  all components are grouped together.

- Unmention legacy display technologies.  Colormapped and monochrome
  displays aren't a thing anymore, and even when they were still a
  thing, it was possible to display full-color images to them.  In 1991,
  when JPEG decompression time was measured in minutes per megapixel, it
  made sense to keep a decompressed copy of JPEG images on disk, in a
  format that could be displayed without further color conversion (since
  color conversion was slow and memory-intensive.)  In 2024, JPEG
  decompression time is measured in milliseconds per megapixel, and
  color conversion is even faster.  Thus, JPEG images can be
  decompressed, displayed, and color-converted (if necessary) "on the
  fly" at speeds too fast for human vision to perceive.  (In fact, your
  TV performs much more complicated decompression algorithms at least 60
  times per second.)

- Document that color quantization (and associated features), GIF
  input/output, Targa input/output, and OS/2 BMP input/output are legacy
  features.  Legacy status doesn't necessarily mean that the features
  are deprecated.  Rather, it is meant to discourage users from using
  features that may be of little or no benefit on modern machines (such
  as low-quality modes that had significant performance advantages in
  the early 1990s but no longer do) and that are maintained on a
  break/fix basis only.

- General wordsmithing, grammar/punctuation policing, and formatting
  tweaks

- Clarify which data precisions each cjpeg input format and each djpeg
  output format supports.

- cjpeg.1: Remove unnecessary and impolitic statement about the -targa
  switch.

- Adjust or remove performance claims to reflect the fact that:
  * On modern machines, the djpeg "-fast" switch has a negligible effect
    on performance.
  * There is a measurable difference between the performance of Floyd-
    Steinberg dithering and no dithering, but it is not likely
    perceptible to most users.
  * There is a measurable difference between the performance of 1-pass
    and 2-pass color quantization, but it is not likely perceptible to
    most users.
  * There is a measurable difference between the performance of
    full-color and grayscale output when decompressing a full-color JPEG
    image, but it is not likely perceptible to most users.
  * IDCT scaling does not necessarily improve performance.  (It
    generally does if the scaling factor is <= 1/2 and generally doesn't
    if the scaling factor is > 1/2, at least on my machine.  The
    performance claim made in jpeg-6b was probably invalidated when we
    merged the additional scaling factors from jpeg-7.)

- Clarify which djpeg switches/output formats cannot be used when
  decompressing lossless JPEG images.

- Remove djpeg hints, since those involve quality vs. speed tradeoffs
  that are no longer relevant for modern machines.

- Remove documentation regarding using color quantization with 16-bit
  data precision.  (Color quantization requires lossy mode.)

- Java: Fix typos in TJDecompressor.decompress12() and
  TJDecompressor.decompress16() documentation.

- jpegtran.1: Fix truncated paragraph

  In a man page, a single quote at the start of a line is interpreted as
  a macro.

  Closes #775

- libjpeg.txt:
  * Mention J16SAMPLE data type (oversight.)
  * Remove statement about extending jdcolor.c.  (libjpeg-turbo is not
    quite as DIY as libjpeg once was.)
  * Remove paragraph about tweaking the various typedefs in jmorecfg.h.
    It is no longer relevant for modern machines.
  * Remove caveat regarding systems with ints less than 16 bits wide.
    (ANSI/ISO C requires an int to be at least 16 bits wide, and
    libjpeg-turbo has never supported non-ANSI compilers.)

- usage.txt:
  * Add copyright header.
  * Document cjpeg -icc, -memdst, -report, -strict, and -version
    switches.
  * Document djpeg -icc, -maxscans, -memsrc, -report, -skip, -crop,
    -strict, and -version switches.
  * Document jpegtran -icc, -maxscans, -report, -strict, and -version
    switches.
2024-06-24 22:11:43 -04:00
DRC
2c5312fd12 cderror.h: Always include all img I/O err messages
The 8-bit-per-sample image I/O modules have always been built with BMP,
GIF, PBMPLUS, and Targa support, and the 12-bit-per-sample image I/O
modules have always been built with only GIF and PBMPLUS support.  In
libjpeg-turbo 2.1.x and prior, cjpeg and djpeg were built with the same
image format support as the image I/O modules.  However, because of the
multi-precision feature introduced in libjpeg-turbo 3.0.x, cjpeg and
djpeg are now always built with support for all image formats.  Thus,
the error message table compiled into cjpeg and djpeg was a superset of
the error message table compiled into the 12-bit-per-sample and
16-bit-per-sample image I/O modules.  If, for example, the
12-bit-per-sample PPM writer threw JERR_PPM_COLORSPACE (== 15, because
it was built with only GIF and PBMPLUS support), then djpeg interpreted
that as JERR_GIF_COLORSPACE (== 15, because it was built with support
for all image formats.)  There was no chance of a buffer overrun, since
the error message table lookup was performed against the table compiled
into cjpeg and djpeg, which contained all possible entries.  However,
this issue caused an incorrect error message to be displayed by cjpeg or
djpeg if a 12-bit-per-sample or 16-bit-per-sample image I/O module threw
an error.  This commit simply removes the *_SUPPORTED #ifdefs from
cderror.h so that all image I/O error messages are always included in
every instance of the image I/O error message table.

Note that a similar issue could have also occurred with the
12-bit-per-sample and 16-bit-per-sample TurboJPEG image I/O functions,
since the 12-bit-per-sample and 16-bit-per-sample image I/O modules
supporting those functions are built with only PBMPLUS support whereas
the library as a whole is built with BMP and PBMPLUS support.
2024-06-13 22:34:23 -04:00
DRC
3c17063ef1 Guard against dupe SOF w/ incorrect source manager
Referring to https://bugzilla.mozilla.org/show_bug.cgi?id=1898606,
attempting to decompress a specially-crafted malformed JPEG image
(specifically an image with a complete 12-bit Start Of Frame segment
followed by an incomplete 8-bit Start Of Frame segment) using the
default marker processor, buffered-image mode, and input prefetching
triggered the following sequence of events:

- When the 12-bit SOF segment was encountered (in the body of
  jpeg_read_header()), the marker processor's read_markers() method
  called the get_sof() function, which processed the 12-bit SOF segment
  and set cinfo->data_precision to 12.

- If the application subsequently called jpeg_consume_input() in a loop
  to prefetch input data, and it didn't stop calling
  jpeg_consume_input() when the function returned JPEG_REACHED_SOS, then
  the 8-bit SOF segment was encountered in the body of
  jpeg_consume_input().  As a result, the marker processor's
  read_markers() method called get_sof(), which started to process the
  8-bit SOF segment and set cinfo->data_precision to 8.

- Since the 8-bit SOF segment was incomplete, the end of the JPEG data
  stream was encountered when get_sof() attempted to read the image
  height, width, and number of components.

- If the fill_input_buffer() method in the application's custom source
  manager incorrectly returned FALSE in response to a prematurely-
  terminated JPEG data stream, then get_sof() returned FALSE while
  attempting to read the image height, width, and number of components
  (before the duplicate SOF check was reached.)  That caused the default
  marker processor's read_markers() method, and subsequently
  jpeg_consume_input(), to return JPEG_SUSPENDED.

- If the application failed to respond to the JPEG_SUSPENDED return
  value and subsequently attempted to call jpeg_read_scanlines(),
  then the data precision check in jpeg_read_scanlines() succeeded
  (because cinfo->data_precision was now 8.)  However, because
  cinfo->data_precision had been 12 during the previous call to
  jpeg_start_decompress(), only the 12-bit version of the main
  controller was initialized, and the cinfo->main->process_data() method
  was undefined.  Thus, a segfault occurred when jpeg_read_scanlines()
  attempted to invoke that method.

Scenarios in which the issue was thwarted:

1. The default source managers handle a prematurely-terminated JPEG data
stream by inserting a fake EOI marker into the data stream.  Thus, when
using one of those source managers, the INPUT_2BYTES() and INPUT_BYTE()
macros (which get_sof() invokes to read the image height, width, and
number of components) succeeded-- albeit with bogus data, since the fake
EOI marker was read into those fields.  The duplicate SOF check in
get_sof() then failed, generating a fatal libjpeg error.

2. When using a custom source manager that correctly returns TRUE in
response to a prematurely-terminated JPEG data stream, the
aforementioned INPUT_2BYTES() and INPUT_BYTE() macros also succeeded
(albeit with bogus data read from the previous bytes of the data
stream), and the duplicate SOF check failed.

3. If the application did not prefetch input data, or if it stopped
invoking jpeg_consume_input() when the function returned
JPEG_REACHED_SOS, then the duplicate SOF segment was not read prior to
the first call to jpeg_read_scanlines().  Thus, the data precision check
in jpeg_read_scanlines() failed.  If the application instead called
jpeg12_read_scanlines() (that is, if it properly supported multiple data
precisions), then the duplicate SOF segment was not read until the body
of jpeg_finish_decompress().  At that point, its only negative effect
was to cause jpeg_finish_decompress() to return FALSE before the
duplicate SOF check was reached.

In other words, this issue depended not only upon an incorrectly-written
source manager but also upon a very specific sequence of API calls.  It
also depended upon the multi-precision feature introduced in
libjpeg-turbo 3.0.x.  When using an 8-bit-per-sample build of
libjpeg-turbo 2.1.x, jpeg_read_header() failed with "Unsupported JPEG
data precision 12" after the 12-bit SOF segment was processed.  When
using a 12-bit-per-sample build of libjpeg-turbo 2.1.x, the behavior
was the same as if the application called jpeg12_read_scanlines() in
Scenario 3 above.

This commit simply moves the duplicate SOF check to the top of
get_sof() so the check will fail before the marker processor attempts to
read the duplicate SOF.  It should be noted that this issue isn't a
libjpeg-turbo bug per se, because it occurs only when the calling
application does something it shouldn't.  It is, rather, an issue of API
hardening/caller-proofing.
2024-05-29 10:08:24 -04:00
DRC
46173635be Remove jpeg_std_message_table[] extern sym comment
jpeg_std_message_table[] was never a documented part of the libjpeg API,
nor was it exposed in jpegint.h or the Windows libjpeg API DLL.  Thus,
it was never a good idea (nor was it even remotely necessary) for
applications to use it.  However, referring to #763 and #767, one
application (RawTherapee) did use it.
34c055851e hid the symbol, which broke the
Un*x builds of RawTherapee.  (RawTherapee already did the right thing on
Windows, because jpeg_std_message_table[] was not exposed in the
Windows libjpeg API DLL.  Referring to
https://github.com/Beep6581/RawTherapee/issues/7074, RawTherapee now
does the right thing on Un*x platforms as well.)

The comment in jerror.c indicated that Tom Lane intended the symbol to
be external "just in case any applications want to refer to it
directly."  However, with respect to libjpeg-turbo, the comment was
effectively already a lie on Windows.  My choices at this point are:

1. Revert 34c055851e and start exposing
   the symbol on Windows, thus making the comment true again.
2. Remove the comment.

Option 1 would have created whiplash, since 3.0.3 has already been
released with the symbol hidden, and that option would have further
encouraged ill-advised behavior on the part of applications.  Since the
issue has already been fixed in RawTherapee, and since it is known to
affect only that application, I chose Option 2.

In my professional opinion, a code comment does not rise to the level
of a contract between a library and a calling application.  In other
words, the comment did not make the symbol part of the API, even though
the symbol was exposed on some platforms.  Applications that use
internal symbols (even the symbols defined in jpegint.h) do so at their
own risk.  There is no guarantee that those symbols will remain
unchanged from release to release, as it is sometimes necessary to
modify the internal (opaque) structures and methods in order to
implement new features or even fix bugs.  Some implementations of the
libjpeg API (such as the one in Jpegli, for instance), do not provide
those internal symbols at all.  Best practices are for applications that
use the internal libjpeg-turbo symbols to provide their own copy of
libjpeg-turbo (for instance, via static linking), so they can manage any
unexpected changes in those symbols.  (In fact, that is how libjpeg was
originally used.  Application developers built it from source with
compile-time options to exclude unneeded functionality.  Thus, no two
builds of libjpeg were guaranteed to be API/ABI-compatible.  The idea of
a libjpeg shared library that exposes a pseudo-standard ABI came later,
and that has always been an awkward fit for an API that was intended to
be modified at compile time to suit specific application needs.
libjpeg-turbo's colorspace extensions are but one example, among many,
of our attempts to reconcile that awkwardness while preserving backward
compatibility with the aforementioned pseudo-standard ABI.)
2024-05-29 00:18:05 -04:00
DRC
9ddcae4a8f jpeglib.h: Document the need to include stdio.h
libjpeg.txt documents the need to "include system headers that define at
least the typedefs FILE and size_t" before including jpeglib.h.
However, some software developers unfortunately assume that any
downstream build failure is due to an upstream oversight (as if such an
oversight would have gone unnoticed for 14 years in a library as
ubiquitous as libjpeg-turbo) and "come in hot" with a proposal and
arguments that have already been carefully considered and rejected
multiple times (as opposed to grepping the documentation or searching
existing issues and PRs to find out whether the upstream behavior is
intentional.)

Multiple issues and PRs (including #17, #18, #116, #737, and #766) have
been filed regarding this, so this commit adds a comment to jpeglib.h in
the hope of heading off future issues and PRs.  I suspect that some
people will still choose to waste my time by arguing about it, even
though the decision was made by Tom Lane nearly 20 years before
libjpeg-turbo even existed, the decision was supportable based on the
needs of early 1990s computing systems, and reversing that decision
would break backward API compatibility (which is one of the reasons that
many downstream projects adopted libjpeg-turbo in the first place.)  At
least now, if someone posts an issue or PR about this again, I can just
link to this commit and close the issue/PR without comment.
2024-05-20 13:03:49 -04:00
DRC
bc491b16e2 ChangeLog.md: Document previous commit 2024-05-16 17:32:02 -04:00
DRC
0fc7313e54 Don't traverse linked list when saving a marker
If the calling application invokes jpeg_save_markers() to save a
particular type of marker, then the save_marker() function will be
invoked for every marker of that type that is encountered.  Previously,
only the head of the marker linked list was stored (in
jpeg_decompress_struct), so save_marker() had to traverse the entire
linked list before it could add a new marker to the tail of the list.
That caused CPU usage to grow exponentially with the number of markers.
Referring to #764, it is possible to create a JPEG image that contains
an excessive number of markers.  The specific reproducer that uncovered
this issue is a specially-crafted 1-megabyte malformed JPEG image with
tens of thousands of APP1 markers, which required approximately 30
seconds of CPU time (on a modern Intel processor) to process.  However,
it should also be possible to create a legitimate JPEG image that
reproduces the issue (such as an image with tens of thousands of
duplicate EXIF tags.)

This commit introduces a new pointer (in jpeg_decomp_master, in order to
preserve backward ABI compatibility) that is used to store the tail of
the marker linked list whenever a marker is added to it.  Thus, it is no
longer necessary to traverse the list when adding a marker, and CPU
usage will grow linearly rather than exponentially with the number of
markers.

Fixes #764
2024-05-14 14:46:33 -04:00
DRC
7fa4b5b762 jerror.c: Silence MSan uninitialized value warning
If an error manager instance is passed to jpeg_std_error(), then its
format_message() method will point to the format_message() function in
jerror.c.  The format_message() function passes all eight values from
the jpeg_error_mgr::msg_parm.i[] array as arguments to
snprintf()/_snprintf_s(), even if the format string doesn't use all of
those values.  Subsequently invoking one of the ERREXIT[1-6]() macros
will leave the unused values uninitialized, and if the
-fsanitize-memory-param-retval option (introduced in Clang 14) is
enabled (which it is by default in Clang 16 and later), then MSan will
complain when the format_message() function tries to pass the
uninitialized-but-unused values as function arguments.

This commit modifies jpeg_std_error() so that it zeroes out the error
manager instance passed to it, thus working around the warning as well
as simplifying the code.

Closes #761
2024-05-06 18:24:15 -04:00
DRC
3f43bb3320 Build: Don't use COMPONENT w/install(INCLUDES ...)
(Regression introduced by 24e09baaf0)

The install() INCLUDES option is not an artifact option.  It specifies
a list of directories that will be added to the
INTERFACE_INCLUDE_DIRECTORIES target property when the target is
exported using the install() EXPORT option, which occurs when CMake
package config files are generated.  Specifying 'COMPONENT include' with
the install() INCLUDES option caused the INTERFACE_INCLUDE_DIRECTORIES
properties in our CMake package config files to contain
'${_IMPORT_PREFIX}/COMPONENT', which caused errors of the form 'Imported
target "libjpeg-turbo::XXXX" includes non-existent path' when downstream
build systems attempted to include libjpeg-turbo using find_package().

Fixes #759
Closes #760
2024-05-06 13:38:59 -04:00
Kleis Auke Wolthuizen
24e09baaf0 Build: Add COMPONENT to all install() commands
This makes it possible for downstream packagers and other integrators of
libjpeg-turbo to include only specific directories from the
libjpeg-turbo installation (or to install specific directories under a
different prefix, etc.)  The names of the components correspond to the
directories into which they will be installed.

Refer to libvips/libvips#3931, #265, #338

Closes #756
2024-05-04 14:36:14 -04:00
DRC
6a522fcda4 jpegtran -drop: Ensure all quant tables defined
It is possible to craft a malformed JPEG image in which all of the
scans contain fewer components than the number of components specified
in the Start Of Frame (SOF) segment.  Attempting to use such an image as
either an input image or a drop image with 'jpegtran -drop' caused a
NULL dereference and subsequent segfault in transupp.c:adjust_quant(),
so this commit adds appropriate checks to guard against that.

Since the issue involved an interface that is only exposed on the
jpegtran command line, it did not represent a security risk.
'jpegtran -drop' could not ever be used successfully with images such as
the ones described above.  This commit simply makes jpegtran fail
gracefully rather than crash.

Fixes #758
2024-05-02 14:54:36 -04:00
DRC
2dfe6c0fe9 CI: Work around segfaults in ASan/MSan jobs
Referring to actions/runner-images#9491, the sanitizers in LLVM 14 that
ships with Ubuntu 22.04 are incompatible with high-entropy address space
layout randomization (ASLR), which is enabled in the GitHub runners via
their use of a newer kernel than ubuntu 22.04 uses.
2024-03-18 14:51:04 -04:00
DRC
710865cf0e Build: Don't explicitly set CMP0065 to NEW
This is no longer necessary, because of
1644bdb7d2.
2024-03-18 12:56:42 -04:00
DRC
fe218ca19c Build: Handle CMAKE_C_COMPILER_ID=AppleClang
Because of 1644bdb7d2, we are now
effectively using the NEW behavior for all CMake policies introduced in
all CMake versions up to and including CMake 3.28.  The NEW behavior for
CMP0025, introduced in CMake 3.0, sets CMAKE_C_COMPILER_ID to
"AppleClang" instead of "Clang" when using Apple's variant of Clang (in
Xcode), so we need to match all values of CMAKE_C_COMPILER_ID that
contain "Clang".

This fixes three issues:

- -O2 was not replaced with -O3 in CMAKE_C_FLAGS_RELWITHDEBINFO.  This
  was a minor issue, since -O3 is now the default in
  CMAKE_C_FLAGS_RELEASE, and we use CMAKE_BUILD_TYPE=Release in our
  official builds.

- The build system erroneously set the default value of FLOATTEST8 and
  FLOATTEST12 to no-fp-contract when compiling for PowerPC or Arm using
  Apple Clang 14+ (effectively reverting
  5b2beb4bc4f41dd9dd2a905cb931b8d5054d909b.)  Because Clang 14+ now
  enables -ffp-contract=on by default, this issue caused floating point
  test failures unless FLOATTEST8 and FLOATTEST12 were overridden.

- The build system set MD5_PPM_3x2_FLOAT_FP_CONTRACT as appropriate for
  GCC, not as appropriate for Clang (effectively reverting
  47656a082091f9c9efda054674522513f4768c6c.)  This also caused floating
  point test failures.

Fixes #753
Closes #755
2024-03-18 12:46:11 -04:00
DRC
dfde1f857d Fix (and test) more Clang 14 compiler warnings
-Woverlength-strings, -Wshift-negative-value, -Wsign-compare
2024-03-08 12:50:32 -05:00
DRC
905ec0fa01 Avoid tautological comparisons
Several TurboJPEG functions store their return value in an unsigned
long long intermediate and compare it against the maximum value of
unsigned long or size_t in order to avoid integer overflow.  However,
such comparisons are tautological (always true, i.e. redundant) unless
the size of unsigned long or size_t is less than the size of unsigned
long long.  Explicitly guarding the comparisons with #if avoids compiler
warnings with -Wtautological-constant-in-range-compare in Clang and also
makes it clear to the reader that the comparisons are only intended for
32-bit code.

Refer to #752
2024-03-08 11:52:38 -05:00
DRC
34c055851e Fix warnings with -Wmissing-variable-declarations 2024-03-06 15:17:08 -05:00
DRC
7bb958b732 12-bit: Don't gen opt Huff tbls if tbls supplied
(regression introduced by e8b40f3c2b)

The documented behavior of the libjpeg API is to compute optimal Huffman
tables when generating 12-bit lossy Huffman-coded JPEG images, unless
the calling application supplies its own Huffman tables.  However,
e8b40f3c2b and
96bc40c1b3 modified
jinit_c_master_control() so that it always set cinfo->optimize_coding to
TRUE when generarating 12-bit lossy Huffman-coded JPEG images, which
prevented calling applications from supplying custom Huffman tables for
such images.

This commit modifies jinit_c_master_control() so that it only overrides
cinfo->optimize_coding when generating 12-bit lossy Huffman-coded JPEG
images if all Huffman table slots are empty or all slots contain default
Huffman tables.  Determining whether the latter is true requires using
memcmp() to compare the allocated Huffman tables with the default
Huffman tables, because:

- The documented behavior of jpeg_set_defaults() is to initialize any
  empty Huffman table slot with the default Huffman table corresponding
  to that slot, regardless of the data precision.  There is also no
  requirement that the data precision be specified prior to calling
  jpeg_set_defaults().  Thus, there is no reliable way to prevent
  jpeg_set_defaults() from initializing empty Huffman table slots with
  default Huffman tables, which are useless for 12-bit data precision.

- There is no requirement that custom Huffman tables be defined prior to
  calling jpeg_set_defaults().  A calling application could call
  jpeg_set_defaults() and modify the values in the default Huffman
  tables rather than allocating new tables.  Thus, there is no reliable
  way to detect whether the allocated Huffman tables contain default
  values without comparing the tables with the default Huffman tables.

Fortunately, comparing the allocated Huffman tables with the default
Huffman tables is the last stop on the logic train, so it won't happen
unless cinfo->data_precision == 12, cinfo->arith_code == FALSE,
cinfo->optimize_coding == FALSE, and one or more Huffman tables are
allocated.  (If the compressor object is reused, this ensures that the
full comparison will be performed at most once.)  Custom Huffman tables
will be flagged as non-default when the first non-default value is
encountered, and the worst case (comparing 400 bytes) is very fast on
modern CPUs anyhow.

Fixes #751
2024-03-04 17:45:40 -05:00
DRC
3202feb08a x86-64 SIMD: Support CET if C compiler enables it
- Detect at configure time, via the __CET__ C preprocessor macro,
  whether the C compiler will include either indirect branch tracking
  (IBT) or shadow stack support, and define a NASM macro (__CET__) if
  so.

- Modify the x86-64 SIMD code so that it includes appropriate endbr64
  instructions (to support IBT) and an appropriate .note.gnu.property
  section (to support both IBT and shadow stack) when __CET__ is
  defined.

Closes #350
2024-02-29 16:37:30 -05:00
DRC
1335547558 x86 SIMD: Capitalize all instruction-like macros
(to improve code readability)
2024-02-29 12:18:49 -05:00
DRC
26fc07c8d1 Build: Set MSVC run-time lib based on IDE config 2024-02-08 12:03:37 -05:00
Alyssa Ross
b6ee1016ab Build: Fix tests w/ emulators that don't check CWD
While QEMU will run executables from the current working directory,
other emulators may not.  It is more reliable to pass the full
executable path to the emulator.  The add_test(NAME ... COMMAND ...)
syntax automatically invokes the emulator (e.g. the command specified
in CMAKE_CROSSCOMPILING_EMULATOR) and passes the full executable path to
it, as long as the first COMMAND argument is the name of a target.  This
cleans up the CMake code somewhat as well, since it is no longer
necessary to manually invoke CMAKE_CROSSCOMPILING_EMULATOR.

Closes #747
2024-01-30 18:26:21 -05:00
DRC
d59b1a3bce Build: Reformat lines longer than 80 columns ...
... to ensure that no function argument starts beyond the 80th column.
2024-01-30 15:40:51 -05:00
DRC
36c51dd3eb GitHub: Update checkout, AWS credentials actions
... to silence deprecation warning regarding Node.js 12 and 16 actions.
2024-01-26 15:55:19 -05:00
DRC
9ef0d03e1e LICENSE.md: zlib License clarifications
Disclaimer: I am not a lawyer, nor do I play one on TV.

Referring to #744, mentioning the zlib License as a license that applies
to libjpeg-turbo is confusing, and it isn't actually necessary, since
the IJG License subsumes the terms of the zlib License in the context of
the libjpeg API library and associated programs.  This was presumably
understood to be the case by Miyasaka-san when he chose the zlib License
for the first libjpeg SIMD extensions.  The libjpeg/SIMD web site
(https://cetus.sakura.ne.jp/softlab/jpeg-x86simd/jpegsimd.html) states
(translated from Japanese): "The terms of use of this SIMD enhanced
version of IJG JPEG software are subject to the terms of use of the
original version of IJG JPEG software."

Detailed analysis of the zlib License terms:

    This software is provided 'as-is', without any express or implied
    warranty.  In no event will the authors be held liable for any
    damages arising from the use of this software.

This text is an almost literal subset of the warranty disclaimer text in
the IJG License.  The IJG License states everything above with only
slight differences in wording, and it further clarifies that the user
assumes all risk as to the software's quality and accuracy and that
vendors of commercial products based on the software must assume all
warranty and liability claims.

    Permission is granted to anyone to use this software for any
    purpose, including commercial applications, and to alter it and
    redistribute it freely, subject to the following restrictions:

This is semantically the same as the permission text in the IJG License,
since "use, copy, modify, and distribute this software (or portions
thereof) for any purpose, without fee" covers "use" for "any purpose,
including commercial applications" as well as alteration and
redistribution.

    1. The origin of this software must not be misrepresented; you must
       not claim that you wrote the original software. If you use this
       software in a product, an acknowledgment in the product
       documentation would be appreciated but is not required.

The IJG License requirement that "If any part of the source code for
this software is distributed, then this README file must be included,
with this copyright and no-warranty notice unaltered; and any additions,
deletions, or changes to the original files must be clearly indicated in
accompanying documentation" (Clause 1), as well as the requirement that
"If only executable code is distributed, then the accompanying
documentation must state that 'this software is based in part on the
work of the Independent JPEG Group'" (Clause 2), satisfies the
requirement of Clause 1 of the zlib License.

    2. Altered source versions must be plainly marked as such, and must
       not be misrepresented as being the original software.

Since Clause 1 of the IJG License applies only to the distribution of
source code, the copyright headers in the source code are effectively
"accompanying documentation" in that case.  This is why we ensure that
the copyright headers of individual source files indicate the year(s) in
which modifications were made by each contributor.  Doing so satisfies
the requirements of both Clause 2 of the zlib License and Clause 1 of
the IJG License.

    3. This notice may not be removed or altered from any source
       distribution.

Clauses 2 and 3 of the zlib License apply only to the source code that
bears that license.  Thus, as applied to the software as a whole, those
requirements of the inbound zlib License are compatible with the
outbound IJG License as long as the IJG License does not contradict
them (which it doesn't.)

NOTE: To be clear, existing source code that bears the zlib License
cannot literally be re-licensed under the IJG License, since that would
violate Clause 3 of the zlib License.  However, when considering the
terms under which the overall library is made available, the IJG License
effectively subsumes the terms of the zlib License.
https://www.gnu.org/licenses/license-compatibility.en.html is a
thorough, albeit somewhat GPL-biased, discussion of license
compatibility.
2024-01-26 15:48:17 -05:00
DRC
7d67c3495f Build/Win: Report CMAKE_MSVC_RUNTIME_LIBRARY value
... when using CMake 3.15+
2024-01-26 10:34:04 -05:00
DRC
17df25f92c Build/Win: Eliminate MSVC run-time DLL dependency
(regression introduced by 1644bdb7d2)

Setting a maximum version in cmake_minimum_required() effectively sets
the behavior to NEW for all policies introduced in all CMake versions up
to and including that maximum version.  The NEW behavior for CMP0091,
introduced in CMake 3.15, uses CMake variables to specify the MSVC
runtime library against which to link, rather than placing the relevant
flags in CMAKE_C_FLAGS*.  Thus, replacing /MD with /MT in CMAKE_C_FLAGS*
no longer has any effect when using CMake 3.15+.
2024-01-26 09:43:58 -05:00
DRC
289df647c0 Build: Add tjdoc target for building TurboJPEG dox 2024-01-23 17:35:53 -05:00
DRC
0ef07927c3 Bump copyright year to 2024 2024-01-23 10:47:40 -05:00
DRC
1644bdb7d2 BUILD: Silence CMake 3.28.x deprecation warning
Closes #740
2024-01-22 14:33:31 -05:00
DRC
5a2353c2da GNUInstallDirs.cmake: Various improvements
- Integrate
  c07bba2730 (diff-1e2deb5301e9481203102fcddd1b2d0d2bf0ddc1cbb445c7f4b6414a3b869ce8)
  so that the default man directory is <CMAKE_INSTALL_PREFIX>/share/man
  on FreeBSD systems.

- For good measure, integrate
  f835f189ae
  so that the default info directory is
  <CMAKE_INSTALL_PREFIX>/share/info on FreeBSD systems, even though we
  don't use that directory.

- Automatically set the CMake variable type to PATH for any
  user-specified CMAKE_INSTALL_*DIR variables.

Addresses concerns raised in #326, #346, #648

Closes #648
2024-01-22 14:15:02 -05:00
DRC
335ed793f9 Assume 3-comp lossls JPEG w/o Adobe marker is RGB
libjpeg-turbo always includes Adobe APP14 markers in the lossless JPEG
images that it generates, but some compressors (e.g. accusoft PICTools
Medical) do not.

Fixes #743
2024-01-19 13:14:21 -05:00
DRC
fa2b6ea092 Eliminate duplicate copies of jpeg_nbits_table
ef9a4e05ba (libjpeg-turbo 1.4.x), which
was based on
https://bug815473.bmoattachments.org/attachment.cgi?id=692126
(https://bugzilla.mozilla.org/show_bug.cgi?id=815473), modified the C
baseline Huffman encoder so that it precomputes jpeg_nbits_table, in
order to facilitate sharing the table among multiple processes.
However, libjpeg-turbo never shared the table, and because the table was
implemented as a static array, f3a8684cd1
(libjpeg-turbo 1.5.x) and 37bae1a0e9
(libjpeg-turbo 2.0.x) each introduced a duplicate copy of the table for
(respectively) the SSE2 baseline Huffman encoder and the C progressive
Huffman encoder.

This commit does the following:
- Move the duplicated code in jchuff.c and jcphuff.c, originally
  introduced in 0cfc4c17b7 and
  37bae1a0e9, into a header
  (jpeg_nbits.h).
- Credit the co-author of 0cfc4c17b7.
  (Refer to https://sourceforge.net/p/libjpeg-turbo/patches/57).
- Modify the SSE2 baseline Huffman encoder so that the C Huffman
  encoders can share its definition of jpeg_nbits_table.
- Move the definition of jpeg_nbits_table into a C source file
  (jpeg_nbits.c) rather than a header, and define the table only if
  USE_CLZ_INTRINSIC is undefined and the SSE2 baseline Huffman encoder
  will not be built.
- Apply hidden symbol visibility to the shared definition of
  jpeg_nbits_table, if the compiler supports the necessary attribute.
  (In practice, only Visual C++ doesn't.)

Closes #114

See also:
https://bugzilla.mozilla.org/show_bug.cgi?id=1501523
2024-01-16 17:33:30 -05:00
DRC
be96fa0a40 Doc: Lossless JPEG clarifications
- Clarify that lossless JPEG is slower than and doesn't compress as well
  as lossy JPEG.  (That should be obvious, because "lossy" literally
  means that data is thrown away.)
- Re-generate TurboJPEG C API documentation using Doxygen 1.9.8.
- Clarify that setting the data_precision field in jpeg_compress_struct
  to 16 requires lossless mode.
- Explain what the predictor selection value actually does.  (Refer to
  Recommendation ITU-T T.81 (1992) | ISO/IEC 10918-1:1994, Section
  H.1.2.1.)
2023-12-14 13:33:46 -05:00
DRC
abeca1f0cc Move official releases to GitHub 2023-11-30 09:36:05 -05:00
DRC
3eee0dd747 ChangeLog.md: "since" = "relative to" 2023-11-29 10:03:49 -05:00
DRC
55d342c788 TurboJPEG: Expose/extend hidden "max pixels" param
TJPARAM_MAXPIXELS was previously hidden and used only for fuzz testing,
but it is potentially useful for calling applications as well,
particularly if they want to guard against excessive memory consumption
by the tj3LoadImage*() functions.  The parameter has also been extended
to decompression and lossless transformation functions/methods, mainly
as a convenience.  (It was already possible for calling applications to
impose their own JPEG image size limits by reading the JPEG header prior
to decompressing or transforming the image.)
2023-11-16 15:36:47 -05:00
DRC
6136a9e285 Java doc: Terminology tweaks
- "function" = "method"
- "decompression and transform functions" = "decompression and transform
  operations" (for consistency with the 2.1.x documentation)
- "return an error" = "throw an error"
- "ceil()" = "Math.ceil()"
2023-11-16 14:23:39 -05:00
DRC
40419472fa SECURITY.md: Further clarify security adv. policy
Security advisories should only be filed against official releases.
2023-11-15 13:42:34 -05:00
DRC
45f018cb22 SECURITY.md: Clarify security advisories policy
Unfortunately, most of the GitHub security advisories filed against
libjpeg-turbo thus far have been the result of non-exploitable API
abuses triggered by randomly-generated test programs and accompanied by
wild claims of denials of service with no demonstrable or even probable
exploit that might cause such a DoS (assuming a service even existed
that used the API in question.)  Security advisories remain private
unless accepted, and I cannot accept them if they do not describe an
actual security issue.  Thus, it's best to steer most users toward
regular bug reports.
2023-11-15 13:20:27 -05:00
DRC
d51830473a tjexampletest.in: Fix code formatting issue
(introduced by 837e471a90)
2023-11-15 11:06:23 -05:00
DRC
8a4ce73c92 tj3Transform(): Range check transform operations 2023-11-15 11:02:42 -05:00
DRC
a27bad6552 tj3Transform(): Ensure JPEG hdr successfully read
Because of the TurboJPEG 3 API overhaul, the legacy decompression and
lossless transformation functions now wrap the new TurboJPEG 3
functions.  For performance reasons, we don't want to read the JPEG
header more than once during the same operation, so the wrapped
functions do not read the header if it has already been read by a
wrapper function.  Initially the TurboJPEG 3 functions used a state
variable to track whether the header had already been read, but
b94041390c made this more robust by using
the libjpeg global decompression state instead.  If a wrapper function
has already read the JPEG header successfully, then the global
decompression state will be DSTATE_READY, and the logic introduced in
b94041390c will prevent the header from
being read again.

A subtle issue arises because tj3DecompressHeader() does not call
jpeg_abort_decompress() if jpeg_read_header() fails.  (That is arguably
a bug, but it has existed since the very first implementation of the
function.)  Depending on the nature of the failure, this can cause
tj3DecompressHeader() to return an error code and leave the libjpeg
global decompression state set to DSTATE_INHEADER.  If a misbehaved
application ignored the error and subsequently called a TurboJPEG
decompression or lossless transformation function, then the function
would fail to read the JPEG header because the global decompression
state was greater than DSTATE_START.  In the case of the decompression
functions, this was innocuous, because jpeg_calc_output_dimensions()
and jpeg_start_decompress() both sanity check the global decompression
state.  However, it was possible for a misbehaved application to call
tj3DecompressHeader() with junk data, ignore the return value, and pass
the same junk data into tj3Transform().  Because tj3DecompressHeader()
left the global decompression state set to DSTATE_INHEADER,
tj3Transform() failed to detect the junk data (because it didn't try to
read the JPEG header), and it called jtransform_request_workspace() with
dinfo->image_width and dinfo->image_height still initialized to 0.
Because jtransform_request_workspace() does not sanity check the
decompression state, a division-by-zero error occurred with certain
combinations of transform options in which TJXOPT_TRIM or TJXOPT_CROP
was specified.  However, it should be noted that TJXOPT_TRIM and
TJXOPT_CROP cannot be expected to work properly without foreknowledge of
the JPEG source image dimensions, which cannot be gained except by
calling tj3DecompressHeader() successfully.  Thus, a calling application
is inviting trouble if it does not check the return value of
tj3DecompressHeader() and sanity check the JPEG source image dimensions
before calling tj3Transform().  This commit softens the failure, but the
failure is still due to improper API usage.
2023-11-14 19:22:43 -05:00
DRC
837e471a90 tjexample.c: Fix error when decompressing
(regression introduced by 300a344d65)

300a344d65 fixed the recompression code
path but also broke the pure decompression code path, because the fix
caused the TurboJPEG decompression instance to be destroyed before
tj3SaveImage() could use it.  Furthermore, the fix in
300a344d65 prevented pixel density
information from being transferred from the input image to the output
image when recompressing.  This commit does the following:

- Modify tjexample.c so that a single TurboJPEG instance is initialized
  for lossless transformation and shared by all code paths.  In addition
  to fixing both of the aforementioned issues, this makes the code more
  readable.

- Extend tjexampletest to test the recompression code path, thus
  ensuring that the issues fixed by this commit and
  300a344d65 are not reintroduced.

- Modify tjexample.c to remove redundant fclose(), tj3Destroy(), and
  tj3Free() calls.
2023-11-14 12:08:02 -05:00
DRC
df9dbff830 TurboJPEG: New param to limit virt array mem usage
This corresponds to max_memory_to_use in the jpeg_memory_mgr struct in
the libjpeg API, except that the TurboJPEG parameter is specified in
megabytes.  Because this is 2023 and computers with less than 1 MB of
memory are not a thing (at least not within the scope of libjpeg-turbo
support), it isn't useful to allow a limit less than 1 MB to be
specified.  Furthermore, because TurboJPEG parameters are signed
integers, if we allowed the memory limit to be specified in bytes, then
it would be impossible to specify a limit larger than 2 GB on 64-bit
machines.  Because max_memory_to_use is a long signed integer,
effectively we can specify a limit of up to 2 petabytes on 64-bit
machines if the TurboJPEG parameter is specified in megabytes.  (2 PB
should be enough for anybody, right?)

This commit also bumps the TurboJPEG API version to 3.0.1.  Since the
TurboJPEG API version no longer tracks the libjpeg-turbo version, it
makes sense to increment the API revision number when adding constants,
to increment the minor version number when adding functions, and to
increment the major version number for a complete overhaul.

This commit also removes the vestigial TJ_NUMPARAM macro, which was
never defined because it proved unnecessary.

Partially implements #735
2023-11-14 10:19:06 -05:00
DRC
bf248a5093 tj3Compress*(): Free virt arrays if mem limit hit
This is very subtle, but if a user specifies a libjpeg virtual array
memory limit via the JPEGMEM environment variable and one of the
tj3Compress*() functions hits that limit, the libjpeg error handler
will be invoked in jpeg_start_compress() (more specifically in
realize_virt_arrays() in jinit_compress_master()) before the libjpeg
global compression state can be incremented.  Thus,
jpeg_abort_compress() will not be called before the tj3Compress*()
function exits, the unrealized virtual arrays will not be freed, and if
the TurboJPEG compression instance is reused, those unrealized virtual
arrays will count against the specified memory limit.  This could cause
subsequent compression operations that require smaller virtual arrays
(or even no virtual arrays at all) to fail when they would otherwise
succeed.  In reality, the vast majority of calling programs would abort
and free the TurboJPEG compression instance if one of the tj3Compress*()
functions failed, but TJBench is a rare exception.  This issue does not
bear documenting because of its subtlety and rarity and because JPEGMEM
is not a documented feature of the TurboJPEG API.

Note that the issue does not exist in the tj3Encode*() and tj3Decode*()
functions, because realize_virt_arrays() is never called in the body of
those functions.  The issue also does not exist in the tj3Decompress*()
and tj3Transform() functions, because those functions ensure that the
JPEG header is read (and thus the libjpeg global decompression state is
incremented) prior to calling a function that calls
realize_virt_arrays() (i.e. jpeg_start_decompress() or
jpeg_read_coefficients().)  If realize_virt_arrays() failed in the body
of jpeg_write_coefficients(), then tj3Transform() would abort without
calling jpeg_abort_compress().  However, since jpeg_start_compress() is
never called in the body of tj3Transform(), no virtual arrays are ever
requested from the compression object, so failing to call
jpeg_abort_compress() would be innocuous.
2023-11-11 15:59:09 -05:00
DRC
220bd76188 turbojpeg.h: Fix broken refs in API documentation
"TJPARAM_DENSITYUNIT" should be "TJPARAM_DENSITYUNITS" (oops.)
2023-11-10 11:08:22 -05:00
DRC
cbdc20fbf4 example.c: Remove comments regarding temp files
Those comments could be confusing to new libjpeg-turbo users, and the
same information already exists in libjpeg.txt and structure.txt.
2023-11-08 11:43:58 -05:00
DRC
7c61794faf jmemsys.h: Remove unused MS-DOS/Mac mem. mgr. code
Those obsolete memory managers have never been included in
libjpeg-turbo, nor has libjpeg-turbo ever claimed to support MS-DOS
or Mac operating systems prior to OS X 10.4 "Tiger."  Note that we
retain the ability to use temp files, even though libjpeg-turbo does
not use them.  This allows downstream implementations to write their own
memory managers that use temp files, if necessary.
2023-11-08 11:16:14 -05:00
DRC
78eaf0d46d tj3*YUV8(): Fix int overflow w/ huge row alignment
If the align parameter was set to an unreasonably large value, such as
0x2000000, strides[0] * ph0 and strides[1] * ph1 could have overflowed
the int datatype and wrapped around when computing (src|dst)Planes[1]
and (src|dst)Planes[2] (respectively.)  This would have caused
(src|dst)Planes[1] and (src|dst)Planes[2] to point to lower addresses in
the YUV buffer than expected, so the worst case would have been a
visually incorrect output image, not a buffer overrun or other
exploitable issue.
2023-11-07 15:39:16 -05:00
DRC
0e2d289fab Bump version to 3.0.2 to prepare for new commits 2023-11-07 12:38:05 -05:00
Kornel
6c9f0897af MozJPEG 4.1.5 2023-10-12 17:52:31 +01:00
DRC
ec32420f6b example.c: Fix 12-bit PPM write w/ big endian CPUs 2023-10-11 16:11:45 -04:00
DRC
5b2beb4bc4 Build: Set FLOATTEST* by default for AArch64, PPC
Because of 47656a0820, we can now
reliably determine the correct default values for FLOATTEST8 and
FLOATTEST12 when using Clang or GCC to build for AArch64 or PowerPC
platforms.  (Testing confirms that this is the case with GCC 5-13 and
Clang 5-14 on Ubuntu/AArch64, GCC 4 on CentOS 7/PPC, and GCC 8-10 and
Clang 6-12 on Ubuntu/PPCLE.)  Other CPU architectures and compilers can
be added on a case-by-case basis as they are tested.
2023-10-11 16:11:36 -04:00
DRC
da48edfc49 jchuff.c: Fix uninit read w/ AArch64, WITH_SIMD=0
Because of bf01ed2fbc, the simd field in
huff_entropy_encoder (and, by extension, the simd field in
savable_state) is only initialized if WITH_SIMD is defined.  Due to an
oversight, the simd field in savable_state was queried in flush_bits()
regardless of whether WITH_SIMD was defined.  In most cases, both
branches of the query have identical code, and the optimizer removes the
branch.  However, because the legacy Neon GAS Huffman encoder uses the
older bit buffer logic from libjpeg-turbo 2.0.x and prior (refer to
087c29e07f), the branches do not have
identical code when building for AArch64 with NEON_INTRINSICS undefined
(which will be the case if WITH_SIMD is undefined.)  Thus, if
libjpeg-turbo was built for AArch64 with the SIMD extensions disabled
at build time, it was possible for the Neon GAS branch in flush_bits()
to be taken, which would have set put_bits to a value that is incorrect
for the C Huffman encoder.  Referring to #728, a user reported that this
issue sometimes caused libjpeg-turbo to generate bogus JPEG images if it
was built for AArch64 without SIMD extensions and subsequently used
through the Qt framework.  (It should be noted, however, that disabling
the SIMD extensions in AArch64 builds of libjpeg-turbo is inadvisable
for performance reasons.)

I was unable to reproduce the issue on Linux/AArch64 using libjpeg-turbo
alone, despite testing various versions of GCC and Clang and various
optimization levels.  However, the issue is reproducible using MSan with
-O0, so this commit also modifies the GitHub Actions workflow so that
compiler optimization is disabled in the linux-msan job.  That should
prevent the issue or similar issues from re-emerging.

Fixes #728
2023-10-10 14:58:34 -04:00
DRC
3d1d68cf96 README.md: Mention 4:4:0 math. incomp. vs. jpeg-6b
libjpeg-turbo implements 4:4:0 "fancy" (smooth) upsampling, which is
enabled by default when decompressing JPEG images that use 4:4:0
chrominance subsampling.  libjpeg did not and does not implement fancy
4:4:0 upsampling.
2023-10-04 13:20:38 -04:00
DRC
2c97a1ff07 GitHub: Use Ubuntu 20.04 runner for x32 build/test
The Ubuntu 22.04 kernel no longer supports the x32 ABI.
2023-10-03 12:08:31 -04:00
DRC
47656a0820 Test: Fix float test errors w/ Clang & fp-contract
The MD5 sums associated with FLOATTEST8=fp-contract and
FLOATTEST12=fp-contract are appropriate for GCC (tested v5 through v13)
with -ffp-contract=fast, which is the default when compiling for an
architecture that has fused multiply-add (FMA) instructions.  However,
different MD5 sums are needed for Clang (tested v5 through v14) with
-ffp-contract=on, which is now the default in Clang 14 when compiling
for an architecture that has FMA instructions.

Refer to #705, #709, #710
2023-10-03 11:28:21 -04:00
Kornel
0c6302e086 Merge remote-tracking branch 'libjpeg-turbo/2.1.x' into HEAD
* libjpeg-turbo/2.1.x:
  ChangeLog.md: List CVE ID fixed by ccaba5d7
  jpeglib.h: Document that JCS_RGB565 is decomp-only
  Fix block smoothing w/vert.-subsampled prog. JPEGs
2023-09-23 22:31:18 +01:00
DRC
4ae5d3dac5 ChangeLog.md: List CVE ID fixed by ccaba5d7
Closes #724
2023-09-14 17:23:13 -04:00
DRC
c0412b56d6 ChangeLog.md: List CVE ID fixed by ccaba5d7
Closes #724
2023-09-14 17:20:37 -04:00
DRC
7722c54c63 jpeglib.h: Document that JCS_RGB565 is decomp-only
Closes #723
2023-09-11 12:47:39 -04:00
DRC
f3c7116eaf jpeglib.h: Document that JCS_RGB565 is decomp-only
Closes #723
2023-09-11 12:46:13 -04:00
Kornel
61e03cc6b2 Fix #220 2023-09-04 15:58:41 +01:00
Kornel
3a691f41f9 Merge commit 'eadd243'
# By DRC
# Via DRC
* commit 'eadd243':
  Fix interblock smoothing with narrow prog. JPEGs
  jchuff.c/flush_bits(): Guard against free_bits < 0
  jchuff.c/flush_bits(): Guard against put_bits < 0
  Restore xform fuzzer behavior from before 19f9d8f0
  xform fuzz: Use src subsamp to calc dst buf size
  Doc: Mention that we are a JPEG ref implementation
  jchuff.c: Test for out-of-range coefficients
  turbojpeg.h: Make customFilter() proto match doc
  ChangeLog.md: Fix typo
  tjTransform(): Calc dst buf size from xformed dims
  Fix build warnings/errs w/ -DNO_GETENV/-DNO_PUTENV
  GitHub: Fix x32 build
  tjexample.c: Prevent integer overflow
  jpeg_crop_scanline: Fix calc w/sclg + 2x4,4x2 samp
  Decomp: Don't enable 2-pass color quant w/ RGB565
  TJBench: w/JPEG input imgs, set min tile= MCU size
  Bump version to 2.1.6 to prepare for new commits
  GitHub: Add pull request template
  Build: Clarify CMAKE_OSX_ARCHITECTURES error
  Build: Fail if included with add_subdirectory()

# Conflicts:
#	.github/workflows/build.yml
#	CMakeLists.txt
#	README.md
#	release/deb-control.in
2023-08-26 21:52:39 +01:00
Kornel
3bd754ee68 Merge tag '2.1.5.1'
# By DRC
# Via DRC
* tag '2.1.5.1':
  ChangeLog.md: Document d743a2c1
  OSS-Fuzz: Bail out immediately on decomp failure
  SIMD/x86: Initialize simd_support before every use
  Build: Define THREAD_LOCAL even if !WITH_TURBOJPEG

# Conflicts:
#	CMakeLists.txt
2023-08-26 21:49:51 +01:00
DRC
a9d87361c8 Fix block smoothing w/vert.-subsampled prog. JPEGs
The 5x5 interblock smoothing implementation, introduced in libjpeg-turbo
2.1, improperly extended the logic from the traditional 3x3 smoothing
implementation.  Both implementations point prev_block_row and
next_block_row to the current block row when processing, respectively,
the first and the last block row in the image:

  if (block_row > 0 || cinfo->output_iMCU_row > 0)
    prev_block_row =
      buffer[block_row - 1] + cinfo->master->first_MCU_col[ci];
  else
    prev_block_row = buffer_ptr;

  if (block_row < block_rows - 1 ||
      cinfo->output_iMCU_row < last_iMCU_row)
    next_block_row =
      buffer[block_row + 1] + cinfo->master->first_MCU_col[ci];
  else
    next_block_row = buffer_ptr;

6d91e950c8 naively extended that logic to
accommodate a 5x5 smoothing window:

  if (block_row > 1 || cinfo->output_iMCU_row > 1)
    prev_prev_block_row =
      buffer[block_row - 2] + cinfo->master->first_MCU_col[ci];
  else
    prev_prev_block_row = prev_block_row;

  if (block_row < block_rows - 2 ||
      cinfo->output_iMCU_row + 1 < last_iMCU_row)
    next_next_block_row =
      buffer[block_row + 2] + cinfo->master->first_MCU_col[ci];
  else
    next_next_block_row = next_block_row;

However, this new logic was only correct if block_rows == 1, so the
values of prev_prev_block_row and next_next_block_row were incorrect
when processing, respectively, the second and second to last iMCU rows
in a vertically-subsampled progressive JPEG image.

The intent was to:
- point prev_block_row to the current block row when processing the
  first block row in the image,
- point prev_prev_block_row to prev_block_row when processing the first
  two block rows in the image,
- point next_block_row to the current block row when processing the
  last block row in the image, and
- point next_next_block_row to next_block_row when processing the last
  two block rows in the image.

This commit modifies decompress_smooth_data() so that it computes the
current block row's position relative to the whole image and sets
the block row pointers based on that value.

This commit also restores a line of code that was accidentally deleted
by 6d91e950c8:

  access_rows += compptr->v_samp_factor; /* prior iMCU row too */

access_rows is merely a sanity check that tells the access_virt_barray()
method to generate an error if accessing the specified number of rows
would cause a buffer overrun.  Essentially, it is a belt-and-suspenders
measure to ensure that j*init_d_coef_controller() allocated enough rows
for the full-image virtual array.  Thus, excluding that line of code did
not cause an observable issue.

This commit also documents eadd2436ee in
the change log.

Fixes #721
2023-08-15 15:40:37 -04:00
DRC
9b704f96b2 Fix block smoothing w/vert.-subsampled prog. JPEGs
The 5x5 interblock smoothing implementation, introduced in libjpeg-turbo
2.1, improperly extended the logic from the traditional 3x3 smoothing
implementation.  Both implementations point prev_block_row and
next_block_row to the current block row when processing, respectively,
the first and the last block row in the image:

  if (block_row > 0 || cinfo->output_iMCU_row > 0)
    prev_block_row =
      buffer[block_row - 1] + cinfo->master->first_MCU_col[ci];
  else
    prev_block_row = buffer_ptr;

  if (block_row < block_rows - 1 ||
      cinfo->output_iMCU_row < last_iMCU_row)
    next_block_row =
      buffer[block_row + 1] + cinfo->master->first_MCU_col[ci];
  else
    next_block_row = buffer_ptr;

6d91e950c8 naively extended that logic to
accommodate a 5x5 smoothing window:

  if (block_row > 1 || cinfo->output_iMCU_row > 1)
    prev_prev_block_row =
      buffer[block_row - 2] + cinfo->master->first_MCU_col[ci];
  else
    prev_prev_block_row = prev_block_row;

  if (block_row < block_rows - 2 ||
      cinfo->output_iMCU_row + 1 < last_iMCU_row)
    next_next_block_row =
      buffer[block_row + 2] + cinfo->master->first_MCU_col[ci];
  else
    next_next_block_row = next_block_row;

However, this new logic was only correct if block_rows == 1, so the
values of prev_prev_block_row and next_next_block_row were incorrect
when processing, respectively, the second and second to last iMCU rows
in a vertically-subsampled progressive JPEG image.

The intent was to:
- point prev_block_row to the current block row when processing the
  first block row in the image,
- point prev_prev_block_row to prev_block_row when processing the first
  two block rows in the image,
- point next_block_row to the current block row when processing the
  last block row in the image, and
- point next_next_block_row to next_block_row when processing the last
  two block rows in the image.

This commit modifies decompress_smooth_data() so that it computes the
current block row's position relative to the whole image and sets
the block row pointers based on that value.

This commit also restores a line of code that was accidentally deleted
by 6d91e950c8:

  access_rows += compptr->v_samp_factor; /* prior iMCU row too */

access_rows is merely a sanity check that tells the access_virt_barray()
method to generate an error if accessing the specified number of rows
would cause a buffer overrun.  Essentially, it is a belt-and-suspenders
measure to ensure that j*init_d_coef_controller() allocated enough rows
for the full-image virtual array.  Thus, excluding that line of code did
not cause an observable issue.

This commit also documents dbae59281f in
the change log.

Fixes #721
2023-08-15 15:21:29 -04:00
DRC
7b844bfda6 x86-64 SIMD: Use std stack frame/prologue/epilogue
This allows debuggers and profilers to reliably capture backtraces from
within the x86-64 SIMD functions.

In places where rbp was previously used to access temporary variables
(after stack alignment), we now use r15 and save/restore it accordingly.
The total amount of work is approximately the same, because the previous
code pushed the pre-alignment stack pointer to the aligned stack.  The
new prologue and epilogue actually have fewer instructions.

Also note that the {un}collect_args macros now use rbp instead of rax to
access arguments passed on the stack, so we save a few instructions
there as well.

Based on:
debcc7c3b4

Closes #707
Closes #708
2023-08-08 12:33:06 -04:00
DRC
e17fa3a271 Bump version to 3.0.1 to prepare for new commits 2023-08-08 11:28:12 -04:00
DRC
eadd2436ee Fix interblock smoothing with narrow prog. JPEGs
Due to an oversight, the assignment of DC05, DC10, DC15, DC20, and DC25
(the right edge coefficients in the 5x5 interblock smoothing window) in
decompress_smooth_data() was incorrect for images exactly two MCU blocks
wide.  For such images, DC04, DC09, DC14, DC19, and DC24 were assigned
values based on the last MCU column, but DC05, DC10, DC15, DC20, and
DC25 were assigned values based on the first MCU column (because
block_num + 1 was never less than last_block_column.)  This commit
modifies jdcoefct.c so that, for images at least two MCU blocks wide,
DC05, DC10, DC15, DC20, and DC25 are assigned the same values as DC04,
DC09, DC14, DC19, and DC24 (respectively.)  DC05, DC10, DC15, DC20, and
DC25 are then immediately overwritten for images more than two MCU
blocks wide.

Since this issue was minor and not likely obvious to an end user, the
fix is undocumented.

Fixes #700
2023-08-03 16:07:54 -04:00
DRC
dbae59281f Fix interblock smoothing with narrow prog. JPEGs
Due to an oversight, the assignment of DC05, DC10, DC15, DC20, and DC25
(the right edge coefficients in the 5x5 interblock smoothing window) in
decompress_smooth_data() was incorrect for images exactly two MCU blocks
wide.  For such images, DC04, DC09, DC14, DC19, and DC24 were assigned
values based on the last MCU column, but DC05, DC10, DC15, DC20, and
DC25 were assigned values based on the first MCU column (because
block_num + 1 was never less than last_block_column.)  This commit
modifies jdcoefct.c so that, for images at least two MCU blocks wide,
DC05, DC10, DC15, DC20, and DC25 are assigned the same values as DC04,
DC09, DC14, DC19, and DC24 (respectively.)  DC05, DC10, DC15, DC20, and
DC25 are then immediately overwritten for images more than two MCU
blocks wide.

Since this issue was minor and not likely obvious to an end user, the
fix is undocumented.

Fixes #700
2023-08-03 15:43:46 -04:00
DRC
300a344d65 tjexample.c: Fix error when recompressing
(regression introduced by fc01f4673b)

Because of the TurboJPEG 3 API overhaul, the pure compression code path
in tjexample.c now creates a TurboJPEG compression instance prior to
calling tj3LoadImage().  However, due to an oversight, a compression
instance was no longer created in the recompression code path.  Thus,
that code path attempted to reuse the TurboJPEG decompression instance,
which caused an error ("tj3Set(): TJPARAM_QUALITY is not applicable to
decompression instances.")  This commit modifies tjexample.c so that the
recompression code path creates a new TurboJPEG compression instance if
one has not already been created.

Fixes #716
2023-07-30 11:20:39 -04:00
DRC
21f5688aa4 jchuff.c/flush_bits(): Guard against free_bits < 0
This fixes a buffer overrun, reported by OSS-Fuzz, that occurred when
attempting to transform a specially-crafted malformed arithmetic-coded
JPEG image into a baseline Huffman-coded JPEG destination image with
default Huffman tables.  This issue probably had a similar root cause to
the issue fixed in 31a301389b, but in this
case, the issue only occurred with the SIMD baseline Huffman encoder in
libjpeg-turbo 2.1.x and 2.0.x.  It was not reproducible in 3.0.x or when
using the C baseline Huffman encoder.  (NOTE: In order to reproduce the
issue with 2.1.x, it was necessary to revert
58cee6d90cd616c86fae142891b987c289ea055a.)
2023-07-25 17:40:35 -04:00
DRC
ebca79d508 xform fuzz: Test optimized baseline entropy coding
Because of d011622f4b, optimized baseline
entropy coding wasn't actually being tested.
2023-07-25 16:47:44 -04:00
DRC
63bd71885f Build: Unset FLOATTEST* by default for non-x86
Because libjpeg-turbo 3.0.x now supports multiple data precisions in the
same build, the regression test system can test the 8-bit and 12-bit
floating point DCT/IDCT algorithms separately.  The expected MD5 sums
for those tests are communicated to the test system using the FLOATTEST8
and FLOATTEST12 CMake variables.  Whereas it is possible to
intelligently set a default value for FLOATTEST8 when building for
x86[-64] and a default value for FLOATTEST12 when building for x86-64,
it is not possible with other architectures.  (Refer to #705, #709,
and #710.)  Clang 14, for example, now enables FMA (fused multiply-add)
instructions by default on architectures that support them, but with
AArch64 builds, the results are not the same as when using GCC/AArch64
with FMA instructions enabled.  Thus, setting FLOATTEST12=fp-contract
doesn't make the tests pass.  It was already impossible to intelligently
set a default for FLOATTEST8 with i386 builds, but referring to #710,
that appears to be the case with other non-x86-64 builds as well.

Back in 1991, when Tom Lane first released libjpeg, some CPUs had
floating point units and some didn't.  It could take minutes to compress
or decompress a 1-megapixel JPEG image using the "slow" integer DCT/IDCT
algorithms, and the floating point algorithms were significantly faster
on systems that had an FPU.  On systems without FPUs, floating point
math was emulated and really slow, so Tom also developed "fast" integer
DCT/IDCT algorithms to speed up JPEG performance, at the expense of
accuracy, on those systems.  Because of libjpeg-turbo's SIMD extensions,
the floating point algorithms are now significantly slower than the
"slow" integer algorithms without being significantly more accurate, and
the "fast" integer algorithms fail the ISO/ITU-T conformance tests
without being any faster than the "slow" integer algorithms on x86
systems.  Thus, the floating point and "fast" integer algorithms are
considered legacy features.

In order for the floating point regression tests to be useful, the
results of the tests must be validated against an independent metric.
(In other words, it wouldn't be useful to use the floating point
DCT/IDCT algorithms to determine the expected results of the floating
point DCT/IDCT algorithms.)  In the past, I attempted without success to
develop a low-level floating point test that would run at configure time
and determine the appropriate default value of FLOATTEST*.  Barring that
approach, the only other possibilities would be:

1. Develop a test framework that compares the floating point results
with a margin of error, as TJUnitTest does.  However, that effort isn't
justified unless it could also benefit non-legacy features.

2. Compare the floating point results against an expected MD5 sum, as we
currently do.  However, as previously described, it isn't possible in
most cases to determine an appropriate default value for the expected
MD5 sum.

For the moment, it makes the most sense to disable the 8-bit floating
point tests by default except with x86[-64] builds and to disable the
12-bit floating point tests by default except with x86-64 builds.  That
means that the floating point algorithms will still be regression tested
when performing x86[-64] builds, but other types of builds will have to
opt in to the same regression tests.  Since the floating point DCT/IDCT
algorithms are unlikely to change ever again (the only reason they still
exist at all is to maintain backward compatibility with libjpeg), this
seems like a reasonable tradeoff.
2023-07-25 13:38:52 -04:00
DRC
d6914b6b1e CMakeLists.txt: Fix comment buglet 2023-07-24 16:41:18 -04:00
DRC
041c80a42e jchuff.c/flush_bits(): Guard against put_bits < 0
This fixes a UBSan negative shift warning, reported by OSS-Fuzz, that
occurred when attempting to transform a specially-crafted malformed
arithmetic-coded JPEG image into a baseline Huffman-coded JPEG
destination image with default Huffman tables.  This issue probably
had a similar root cause to the issue fixed in
31a301389b, but in this case, the issue
only occurred with the SIMD baseline Huffman encoder in libjpeg-turbo
2.1.x.  It was not reproducible in 2.0.x or 3.0.x or when using the
C baseline Huffman encoder.
2023-07-12 14:16:13 -04:00
DRC
e429e379b0 tjunittest.c: Use _getpid() on Windows 2023-07-06 16:58:20 -04:00
DRC
035ea386d1 Build: Fix regression test concurrency issues
- The example-*bit-*-decompress test must run after the
  example-*bit-*-compress test, since the latter generates
  testout*-example.jpg.

- Add -static to the filenames of all output files generated by the
  "static" regression tests, to avoid conflicts with the "shared"
  regression tests.

- Add the PID to the filenames of all files generated by the tjunittest
  packed-pixel image I/O tests.

- Check the return value of MD5File() in tjunittest to avoid a segfault
  if the file doesn't exist.  (Prior to the fix described above, that
  could occur if two instances of tjunittest ran concurrently from the
  same directory with the same -bmp and -precision arguments.)

Fixes #705
2023-07-06 14:08:07 -04:00
DRC
d011622f4b Restore xform fuzzer behavior from before c8d52f1c
The intent was for the final transform operation to be the same as the
first transform operation but without TJXOPT_COPYNONE or
TJPARAM_NOREALLOC.  Unrolling the transform operations in
c8d52f1c4c accidentally changed that.
2023-07-06 10:56:34 -04:00
DRC
58cee6d90c Restore xform fuzzer behavior from before 19f9d8f0
The intent was for the final transform operation to be the same as the
first transform operation but without TJXOPT_COPYNONE or
TJFLAG_NOREALLOC.  Unrolling the transform operations in
19f9d8f0fd accidentally changed that.
2023-07-06 10:29:27 -04:00
DRC
f48f73d4ec xform fuzz: Use src subsamp to calc dst buf size
Referring to
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60379
there are some specially-crafted malformed JPEG images that, when
transformed to grayscale, will exceed the worst-case transformed
grayscale JPEG image size.  This is similar in nature to the issue fixed
by 19f9d8f0fd, except that in this case,
the issue occurs regardless of the amount of metadata in the source
image.  Also, the tjTransform() function, the
Java_org_libjpegturbo_turbojpeg_TJTransformer_transform() JNI function,
and TJBench were behaving correctly in this case, because the TurboJPEG
API documentation specifies that the source image's subsampling type
should be used when computing the worst-case transformed JPEG image
size.  (However, only the Java API documentation specified that.  Oops.
The C API documentation now does as well.)  The documented usage
mitigates the issue, and only the transform fuzzer did not adhere to
that.  Thus, this was an issue with the fuzzer itself rather than an
issue with the library.
2023-07-06 09:10:30 -04:00
DRC
895287572d xform fuzz: Use src subsamp to calc dst buf size
Referring to
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60379
there are some specially-crafted malformed JPEG images that, when
transformed to grayscale, will exceed the worst-case transformed
grayscale JPEG image size.  This is similar in nature to the issue fixed
by c8d52f1c4c, except that in this case,
the issue occurs regardless of the amount of metadata in the source
image.  Also, the tj3Transform() function, the
Java_org_libjpegturbo_turbojpeg_TJTransformer_transform() JNI function,
and TJBench were behaving correctly in this case, because the TurboJPEG
API documentation specifies that the source image's subsampling type
should be used when computing the worst-case transformed JPEG image
size.  (However, only the Java API documentation specified that.  Oops.
The C API documentation now does as well.)  The documented usage
mitigates the issue, and only the transform fuzzer did not adhere to
that.  Thus, this was an issue with the fuzzer itself rather than an
issue with the library.
2023-07-06 08:48:40 -04:00
DRC
30c21e559d OSS-Fuzz: Ignore tj3DecompressHeader() return val
Unlike its predecessors, tj3DecompressHeader() does not fail if passed
a JPEG image with an unknown subsampling type.  This led me to believe
that it was OK for the fuzzers to abort if tj3DecompressHeader()
returned an error.  However, there are apparently some malformed JPEG
images that can expose issues in libjpeg-turbo while also causing
tj3DecompressHeader() to complain about header errors.  Thus, it is best
to ignore the return value of tj3DecompressHeader(), as the fuzzers in
libjpeg-turbo 2.1.x and prior did.
2023-07-05 16:13:34 -04:00
DRC
926f1f3daf README.md: Include GitHub Sponsors link/button
Closes #706
2023-07-05 12:43:22 -04:00
DRC
383286702c Doc: Mention that we are a JPEG ref implementation 2023-07-05 10:57:48 -04:00
DRC
762f8b4f21 Doc: Mention that we are a JPEG ref implementation 2023-07-05 10:56:42 -04:00
DRC
6c87537f60 AppVeyor: Use SignPath release cert/only sign tags
The SignPath release certificate for our project is not yet available as
of this writing, but this commit prepares the CI system to use the
release certificate whenever it becomes available.  It also restricts
signing only to tags, which correspond to official releases.  (That
mimics our traditional policy of not signing pre-release builds.)
2023-07-03 10:31:35 -04:00
DRC
31a301389b jchuff.c: Test for out-of-range coefficients
Restore two coefficient range checks from libjpeg to the C baseline
Huffman encoder.  This fixes an issue
(https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60253) whereby
the encoder could read from uninitialized memory when attempting to
transform a specially-crafted malformed arithmetic-coded JPEG source
image into a baseline Huffman-coded JPEG destination image with default
Huffman tables.  More specifically, the out-of-range coefficients caused
r to equal 256, which overflowed the actbl->ehufsi[] array.  Because the
overflow was contained within the huff_entropy_encoder structure, this
issue was not exploitable (nor was it observable at all on x86 or Arm
CPUs unless JSIMD_NOHUFFENC=1 or JSIMD_FORCENONE=1 was set in the
environment or unless libjpeg-turbo was built with WITH_SIMD=0.)

The fix is performance-neutral (+/- 1-2%) for x86-64 code and causes a
0-4% (avg. 1-2%, +/- 1-2%) compression regression for i386 code on Intel
CPUs when the C baseline Huffman encoder is used (JSIMD_NOHUFFENC=1).
The fix is performance-neutral (+/- 1-2%) on Intel CPUs when all of the
libjpeg-turbo SIMD extensions are disabled (JSIMD_FORCENONE=1).  The fix
causes a 0-2% (avg. <1%, +/- 1%) compression regression for PowerPC
code.
2023-07-01 08:20:38 -04:00
DRC
02b074fd90 xform fuzz: Use only xform opts to set entropy alg
This is subtle, but the tj3DecompressHeader() function sets the values
of TJPARAM_ARITHMETIC, TJPARAM_OPTIMIZE, and TJPARAM_PROGRESSIVE.
Unless we unset those values, the entropy algorithm used in the
transformed JPEG image will be determined by the union of the parameter
values and the transform options, which isn't what we want.
2023-07-01 08:14:44 -04:00
DRC
e0c53aa38f jchuff.c: Test for out-of-range coefficients
Restore two coefficient range checks from libjpeg to the C baseline
Huffman encoder.  This fixes an issue
(https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60253) whereby
the encoder could read from uninitialized memory when attempting to
transform a specially-crafted malformed arithmetic-coded JPEG source
image into a baseline Huffman-coded JPEG destination image with default
Huffman tables.  More specifically, the out-of-range coefficients caused
r to equal 256, which overflowed the actbl->ehufsi[] array.  Because the
overflow was contained within the huff_entropy_encoder structure, this
issue was not exploitable (nor was it observable at all on x86 or Arm
CPUs unless JSIMD_NOHUFFENC=1 or JSIMD_FORCENONE=1 was set in the
environment or unless libjpeg-turbo was built with WITH_SIMD=0.)

The fix is performance-neutral (+/- 1-2%) for x86-64 code and causes a
0-4% (avg. 1-2%, +/- 1-2%) compression regression for i386 code on Intel
CPUs when the C baseline Huffman encoder is used (JSIMD_NOHUFFENC=1).
The fix is performance-neutral (+/- 1-2%) on Intel CPUs when all of the
libjpeg-turbo SIMD extensions are disabled (JSIMD_FORCENONE=1).  The fix
causes a 0-2% (avg. <1%, +/- 1%) compression regression for PowerPC
code.
2023-07-01 07:56:50 -04:00
DRC
369b84a4ee turbojpeg.h: Make customFilter() proto match doc 2023-06-30 10:20:20 -04:00
DRC
4a831d6e48 turbojpeg.h: Make customFilter() proto match doc
Closes #704
2023-06-30 10:15:40 -04:00
DRC
53aafa949a ChangeLog.md: Fix typo 2023-06-29 17:45:21 -04:00
DRC
240a5a5cbb ChangeLog.md: Fix typo 2023-06-29 17:45:07 -04:00
DRC
7173889223 djpeg: Fix -map option with 12-bit data precision 2023-06-29 16:36:43 -04:00
DRC
bf9f319cb4 Disallow color quantization with lossless decomp
Color quantization is a legacy feature that serves little or no purpose
with lossless JPEG images.  9f756bc67a
eliminated interaction issues between the lossless decompressor and the
color quantizers related to out-of-range 12-bit samples, but referring
to #701, other interaction issues apparently still exist.  Such issues
are likely, given the fact that the color quantizers were not designed
with lossless decompression in mind.

This commit reverts 9f756bc67a, since the
issues it fixed are no longer relevant because of this commit and
2192560d74.

Fixed #672
Fixes #673
Fixes #674
Fixes #676
Fixes #677
Fixes #678
Fixes #679
Fixes #681
Fixes #683
Fixes #701
2023-06-29 16:36:29 -04:00
DRC
19f9d8f0fd tjTransform(): Calc dst buf size from xformed dims
When used with TJFLAG_NOREALLOC and with TJXOP_TRANSPOSE,
TJXOP_TRANSVERSE, TJXOP_ROT90, or TJXOP_ROT270, tjTransform()
incorrectly based the destination buffer size for a transform on the
source image dimensions rather than the transformed image dimensions.
This was apparently a long-standing bug that had existed in the
tjTransform() function since its inception.  As initially implemented in
the evolving libjpeg-turbo v1.2 code base, tjTransform() required
dstSizes[i] to be set regardless of whether TJFLAG_NOREALLOC was set.
ff78e37595, which was introduced later in
the evolving libjpeg-turbo v1.2 code base, removed that requirement and
planted the seed for the bug.  However, the bug was not activated until
9b49f0e4c7 was introduced still later in
the evolving libjpeg-turbo v1.2 code base, adding a subsampling type
argument to the (new at the time) tjBufSize() function and thus making
the width and height arguments no longer commutative.

The bug opened up the possibility that a JPEG source image could cause
tjTransform() to overflow the destination buffer for a transform if all
of the following were true:
- The JPEG source image used 4:2:2, 4:4:0, or 4:1:1 subsampling.  (These
  are the only supported subsampling types for which the width and
  height arguments to tjBufSize() are not commutative.)
- The width and height of the JPEG source image were such that
  tjBufSize(height, width, subsamplingType) returned a smaller value
  than tjBufSize(width, height, subsamplingType).
- The JPEG source image contained enough metadata that the size of the
  transformed image was larger than
  tjBufSize(height, width, subsamplingType).
- TJFLAG_NOREALLOC was set.
- TJXOP_TRANSPOSE, TJXOP_TRANSVERSE, TJXOP_ROT90, or TJXOP_ROT270 was
  used.
- TJXOPT_COPYNONE was not set.
- TJXOPT_CROP was not set.
- The calling program allocated
  tjBufSize(height, width, subsamplingType) bytes for the
  destination buffer, as the API documentation instructs.

The API documentation cautions that JPEG source images containing a
large amount of extraneous metadata (EXIF, IPTC, ICC, etc.) cannot
reliably be transformed if TJFLAG_NOREALLOC is set and TJXOPT_COPYNONE
is not set.  Irrespective of the bug, there are still cases in which a
JPEG source image with a large amount of metadata can, when transformed,
exceed the worst-case transformed JPEG image size.  For instance, if you
try to losslessly crop a JPEG image with 3 kB of EXIF data to 16x16
pixels, then you are guaranteed to exceed the worst-case 16x16 JPEG
image size unless you discard the EXIF data.

Even without the bug, tjTransform() will still fail with "Buffer passed
to JPEG library is too small" when attempting to transform JPEG source
images that meet the aforementioned criteria.  The bug is that the
function segfaults rather than failing gracefully, but the chances of
that occurring in a real-world application are very slim.  Any
real-world application developers who attempted to transform arbitrary
JPEG source images with TJFLAG_NOREALLOC set would very quickly realize
that they cannot reliably do that without also setting TJXOPT_COPYNONE.
Thus, I posit that the actual risk posed by this bug is low.
Applications such as web browsers that are the most exposed to security
risks from arbitrary JPEG source images do not use the TurboJPEG
lossless transform feature.  (None of those applications even use the
TurboJPEG API, to the best of my knowledge, and the public libjpeg API
has no equivalent transform function.)  Our only command-line interface
to the tjTransform() function, TJBench, was not exposed to the bug
because it had a compatible bug whereby it allocated the JPEG
destination buffer to the same size that tjTransform() erroneously
expected.  The TurboJPEG Java API was also not exposed to the bug
because of a similar compatible bug in the
Java_org_libjpegturbo_turbojpeg_TJTransformer_transform() JNI function.
(This commit fixes both compatible bugs.)

In short, best practices for tjTransform() are to use TJFLAG_NOREALLOC
only with JPEG source images that are known to be free of metadata (such
as images generated by tjCompress*()) or to use TJXOPT_COPYNONE along
with TJFLAG_NOREALLOC.  Still, however, the function shouldn't segfault
as long as the calling program allocates the suggested amount of space
for the JPEG destination buffer.

Usability notes:
tjTransform() could hypothetically require dstSizes[i] to be set
regardless of whether TJFLAG_NOREALLOC is set, but there are usability
pitfalls either way.  The main pitfall I sought to avoid with
ff78e37595 was a calling program failing
to set dstSizes[i] at all, thus leaving its value undefined.  It could
be argued that requiring dstSizes[i] to be set in all cases is more
consistent, but it could also be argued that not requiring it to be set
when TJFLAG_NOREALLOC is set is more user-proof.  tjTransform() could
also hypothetically set TJXOPT_COPYNONE automatically when
TJFLAG_NOREALLOC is set, but that could lead to user confusion.
2023-06-28 11:37:53 -04:00
DRC
c8d52f1c4c tj3Transform: Calc dst buf size from xformed dims
When used with TJPARAM_NOREALLOC and with TJXOP_TRANSPOSE,
TJXOP_TRANSVERSE, TJXOP_ROT90, or TJXOP_ROT270, tj3Transform()
incorrectly based the destination buffer size for a transform on the
source image dimensions rather than the transformed image dimensions.
This was apparently a long-standing bug that had existed in the
tj*Transform() function since its inception.  As initially implemented
in the evolving libjpeg-turbo v1.2 code base, tjTransform() required
dstSizes[i] to be set regardless of whether TJFLAG_NOREALLOC (the
predecessor to TJPARAM_NOREALLOC) was set.
ff78e37595, which was introduced later in
the evolving libjpeg-turbo v1.2 code base, removed that requirement and
planted the seed for the bug.  However, the bug was not activated until
9b49f0e4c7 was introduced still later in
the evolving libjpeg-turbo v1.2 code base, adding a subsampling type
argument to the (new at the time) tjBufSize() function and thus making
the width and height arguments no longer commutative.

The bug opened up the possibility that a JPEG source image could cause
tj3Transform() to overflow the destination buffer for a transform if all
of the following were true:
- The JPEG source image used 4:2:2, 4:4:0, 4:1:1, or 4:4:1 subsampling.
  (These are the only subsampling types for which the width and height
  arguments to tj3JPEGBufSize() are not commutative.)
- The width and height of the JPEG source image were such that
  tj3JPEGBufSize(height, width, subsamplingType) returned a smaller
  value than tj3JPEGBufSize(width, height, subsamplingType).
- The JPEG source image contained enough metadata that the size of the
  transformed image was larger than
  tj3JPEGBufSize(height, width, subsamplingType).
- TJPARAM_NOREALLOC was set.
- TJXOP_TRANSPOSE, TJXOP_TRANSVERSE, TJXOP_ROT90, or TJXOP_ROT270 was
  used.
- TJXOPT_COPYNONE was not set.
- TJXOPT_CROP was not set.
- The calling program allocated
  tj3JPEGBufSize(height, width, subsamplingType) bytes for the
  destination buffer, as the API documentation instructs.

The API documentation cautions that JPEG source images containing a
large amount of extraneous metadata (EXIF, IPTC, ICC, etc.) cannot
reliably be transformed if TJPARAM_NOREALLOC is set and TJXOPT_COPYNONE
is not set.  Irrespective of the bug, there are still cases in which a
JPEG source image with a large amount of metadata can, when transformed,
exceed the worst-case transformed JPEG image size.  For instance, if you
try to losslessly crop a JPEG image with 3 kB of EXIF data to 16x16
pixels, then you are guaranteed to exceed the worst-case 16x16 JPEG
image size unless you discard the EXIF data.

Even without the bug, tj3Transform() will still fail with "Buffer passed
to JPEG library is too small" when attempting to transform JPEG source
images that meet the aforementioned criteria.  The bug is that the
function segfaults rather than failing gracefully, but the chances of
that occurring in a real-world application are very slim.  Any
real-world application developers who attempted to transform arbitrary
JPEG source images with TJPARAM_NOREALLOC set would very quickly realize
that they cannot reliably do that without also setting TJXOPT_COPYNONE.
Thus, I posit that the actual risk posed by this bug is low.
Applications such as web browsers that are the most exposed to security
risks from arbitrary JPEG source images do not use the TurboJPEG
lossless transform feature.  (None of those applications even use the
TurboJPEG API, to the best of my knowledge, and the public libjpeg API
has no equivalent transform function.)  Our only command-line interface
to the tj3Transform() function, TJBench, was not exposed to the bug
because it had a compatible bug whereby it allocated the JPEG
destination buffer to the same size that tj3Transform() erroneously
expected.  The TurboJPEG Java API was also not exposed to the bug
because of a similar compatible bug in the
Java_org_libjpegturbo_turbojpeg_TJTransformer_transform() JNI function.
(This commit fixes both compatible bugs.)

In short, best practices for tj3Transform() are to use TJPARAM_NOREALLOC
only with JPEG source images that are known to be free of metadata (such
as images generated by tj3Compress*()) or to use TJXOPT_COPYNONE along
with TJPARAM_NOREALLOC.  Still, however, the function shouldn't segfault
as long as the calling program allocates the suggested amount of space
for the JPEG destination buffer.

Usability notes:
tj3Transform() could hypothetically require dstSizes[i] to be set
regardless of the value of TJPARAM_NOREALLOC, but there are usability
pitfalls either way.  The main pitfall I sought to avoid with
ff78e37595 was a calling program failing
to set dstSizes[i] at all, thus leaving its value undefined.  It could
be argued that requiring dstSizes[i] to be set in all cases is more
consistent, but it could also be argued that not requiring it to be set
when TJPARAM_NOREALLOC is set is more user-proof.  tj3Transform() could
also hypothetically set TJXOPT_COPYNONE automatically when
TJPARAM_NOREALLOC is set, but that could lead to user confusion.
Ultimately, I would like to address these issues in TurboJPEG v4 by
using managed buffer objects, but that would be an extensive overhaul.
2023-06-27 18:36:01 -04:00
DRC
6b9e3b0400 README.md: Include link to project home page
(for compliance with SignPath's Code of Conduct for Open Source
projects)
2023-06-19 11:11:16 -04:00
DRC
41b18e8d61 AppVeyor: Only add installers to zip file
Oops
2023-06-18 12:50:47 -04:00
DRC
a403ad5b52 AppVeyor: Integrate with SignPath.io 2023-06-16 16:16:42 -04:00
DRC
fcfd2ada75 Fix build warnings/errs w/ -DNO_GETENV/-DNO_PUTENV
- strtest.c: Fix unused variable warnings if both -DNO_GETENV and
  -DNO_PUTENV are specified or if only -DNO_GETENV is specified.

- jinclude.h: Fix build error if only -DNO_GETENV is specified.

Fixes #697
2023-06-16 11:55:01 -04:00
DRC
58cbda3e37 GitHub: Fix x32 build
1f55ae7b0f accidentally overrode the value
of CMAKE_C_FLAGS, thus eliminating the -mx32 flag that was necessary to
enable x32.
2023-06-16 11:54:34 -04:00
DRC
c27695a193 Fix build warnings/errs w/ -DNO_GETENV/-DNO_PUTENV
- strtest.c: Fix unused variable warnings if both -DNO_GETENV and
  -DNO_PUTENV are specified or if only -DNO_GETENV is specified.

- jinclude.h: Fix build error if only -DNO_GETENV is specified.

Fixes #697
2023-06-16 11:39:10 -04:00
DRC
65a85ce34e GitHub: Fix x32 build
1f55ae7b0f accidentally overrode the value
of CMAKE_C_FLAGS, thus eliminating the -mx32 flag that was necessary to
enable x32.
2023-06-16 11:19:33 -04:00
DRC
0e9683c4c6 Bump version to 3.0.0 2023-06-12 14:36:18 -04:00
DRC
be678e5a1b tjexample.c: Prevent integer overflow
Because width, height, and tjPixelSize[] are signed integers, signed
integer overflow will occur if width * height *
tjPixelSize[pixelFormat] > INT_MAX or jpegSize > INT_MAX, which would
cause an incorrect value to be passed to tjAlloc().  This commit
modifies tjexample.c in the following ways:

- Use malloc() rather than tjAlloc() to allocate the uncompressed image
  buffer.  (tjAlloc() is only necessary for JPEG buffers that will
  potentially be reallocated by the TurboJPEG API library.)

- Implicitly promote width, height, and tjPixelSize[pixelFormat] to
  size_t before multiplying them.

- If size_t is 32-bit, throw an error if width * height *
  tjPixelSize[pixelFormat] would overflow the data type.

- Throw an error if jpegSize would overflow a signed integer (which
  could only happen on a 64-bit machine.)

Since tjexample is not installed or packaged, the worst case for this
issue was that a downstream application might interpret tjexample.c
literally and introduce a similar overflow issue into its own code.
However, it's worth noting that such issues could also be introduced
when using malloc().
2023-06-02 11:02:11 -04:00
DRC
6b506ed397 tjexample.c: Prevent integer overflow
Because width, height, and tjPixelSize[] are signed integers, signed
integer overflow will occur if width * height *
tjPixelSize[pixelFormat] > INT_MAX, which would cause an incorrect value
to be passed to tj3Alloc().  This commit modifies tjexample.c in the
following ways:

- Implicitly promote width, height, and tjPixelSize[pixelFormat] to
  size_t before multiplying them.

- Use malloc() rather than tj3Alloc() to allocate the uncompressed image
  buffer.  (tj3Alloc() is only necessary for JPEG buffers that will
  potentially be reallocated by the TurboJPEG API library.)

- If size_t is 32-bit, throw an error if width * height *
  tjPixelSize[pixelFormat] would overflow the data type.

Since tjexample is not installed or packaged, the worst case for this
issue was that a downstream application might interpret tjexample.c
literally and introduce a similar overflow issue into its own code.
However, it's worth noting that such issues could also be introduced
when using malloc().
2023-06-01 14:22:13 -04:00
DRC
2192560d74 Disallow merged upsampling with lossless decomp
Colorspace conversion is explicitly not supported with lossless JPEG
images.  Merged upsampling implies YCbCr-to-RGB colorspace conversion,
so allowing it with lossless decompression was an oversight.
9f756bc67a eliminated interaction issues
between the lossless decompressor and the merged upsampler related to
out-of-range 12-bit samples, but referring to #690, other interaction
issues apparently still exist.  Such issues are likely, given the fact
that the merged upsampler was never designed with lossless decompression
in mind.

This commit also extends the decompress fuzzer so that it catches the
issue reported in #690.

Fixes #690
Redundantly fixes #670
Redundantly fixes #675
2023-05-31 14:42:49 -04:00
DRC
4e7ff7b922 SECURITY.md: Wordsmithing and clarifications
- Clarify that encrypted e-mail is optional.
- Mention the new GitHub security advisory system.
- Clarify that vulnerabilities against new features that are not yet in
  a Stable release series need not be reported securely.
2023-05-31 10:28:38 -04:00
DRC
10693e6441 GitHub: Add security policy 2023-05-30 18:22:50 -04:00
DRC
36aaeebb55 ChangeLog.md: List CVE ID fixed by 9f756bc6 2023-05-30 17:46:58 -04:00
DRC
2e1b8a462f jpeg_crop_scanline: Fix calc w/sclg + 2x4,4x2 samp
When computing the downsampled width for a particular component,
jpeg_crop_scanline() needs to take into account the fact that the
libjpeg code uses a combination of IDCT scaling and upsampling to
implement 4x2 and 2x4 upsampling with certain decompression scaling
factors.  Failing to account for that led to incomplete upsampling of
4x2- or 2x4-subsampled components, which caused the color converter to
read from uninitialized memory.  With 12-bit data precision, this caused
a buffer overrun or underrun and subsequent segfault if the
uninitialized memory contained a value that was outside of the valid
sample range (because the color converter uses the value as an array
index.)

Fixes #669
2023-04-06 22:05:10 -05:00
DRC
3a53627306 jpeg_crop_scanline: Fix calc w/sclg + 2x4,4x2 samp
When computing the downsampled width for a particular component,
jpeg_crop_scanline() needs to take into account the fact that the
libjpeg code uses a combination of IDCT scaling and upsampling to
implement 4x2 and 2x4 upsampling with certain decompression scaling
factors.  Failing to account for that led to incomplete upsampling of
4x2- or 2x4-subsampled components, which caused the color converter to
read from uninitialized memory.  With 12-bit data precision, this caused
a buffer overrun or underrun and subsequent segfault if the
uninitialized memory contained a value that was outside of the valid
sample range (because the color converter uses the value as an array
index.)

Fixes #669
2023-04-06 22:00:43 -05:00
DRC
42ce199c9c Decomp: Don't enable 2-pass color quant w/ RGB565
The 2-pass color quantization algorithm assumes 3-sample pixels.  RGB565
is the only 3-component colorspace that doesn't have 3-sample pixels, so
we need to treat it as a special case when determining whether to enable
2-pass color quantization.  Otherwise, attempting to initialize 2-pass
color quantization with an RGB565 output buffer could cause
prescan_quantize() to read from uninitialized memory and subsequently
underflow/overflow the histogram array.

djpeg is supposed to fail gracefully if both -rgb565 and -colors are
specified, because none of its destination managers (image writers)
support color quantization with RGB565.  However, prescan_quantize() was
called before that could occur.  It is possible but very unlikely that
these issues could have been reproduced in applications other than
djpeg.  The issues involve the use of two features (12-bit precision and
RGB565) that are incompatible, and they also involve the use of two
rarely-used legacy features (RGB565 and color quantization) that don't
make much sense when combined.

Fixes #668
Fixes #671
Fixes #680
2023-04-04 20:45:16 -05:00
DRC
62590d428b Decomp: Don't enable 2-pass color quant w/ RGB565
The 2-pass color quantization algorithm assumes 3-sample pixels.  RGB565
is the only 3-component colorspace that doesn't have 3-sample pixels, so
we need to treat it as a special case when determining whether to enable
2-pass color quantization.  Otherwise, attempting to initialize 2-pass
color quantization with an RGB565 output buffer could cause
prescan_quantize() to read from uninitialized memory and subsequently
underflow/overflow the histogram array.

djpeg is supposed to fail gracefully if both -rgb565 and -colors are
specified, because none of its destination managers (image writers)
support color quantization with RGB565.  However, prescan_quantize() was
called before that could occur.  It is possible but very unlikely that
these issues could have been reproduced in applications other than
djpeg.  The issues involve the use of two features (12-bit precision and
RGB565) that are incompatible, and they also involve the use of two
rarely-used legacy features (RGB565 and color quantization) that don't
make much sense when combined.

Fixes #668
Fixes #671
Fixes #680
2023-04-04 20:38:00 -05:00
DRC
9f756bc67a Lossless decomp: Range-limit 12-bit samples
12-bit is the only data precision for which the range of the sample data
type exceeds the valid sample range, so it is possible to craft a 12-bit
lossless JPEG image that contains out-of-range 12-bit samples.
Attempting to decompress such an image using color quantization or merged
upsampling (NOTE: libjpeg-turbo cannot generate YCbCr or subsampled
lossless JPEG images, but it can decompress them) caused segfaults or
buffer overruns when those algorithms attempted to use the out-of-range
sample values as array indices.  This commit modifies the lossless
decompressor so that it range-limits the output of the scaler when using
12-bit samples.

Fixes #670
Fixes #672
Fixes #673
Fixes #674
Fixes #675
Fixes #676
Fixes #677
Fixes #678
Fixes #679
Fixes #681
Fixes #683
2023-04-04 20:37:54 -05:00
DRC
3f43c6a310 jdlossls.c: Code formatting tweak 2023-04-04 13:27:11 -05:00
DRC
d491094b41 Build separate static/shared jpeg12/16 obj libs
If PIC isn't enabled for the entire build (using
CMAKE_POSITION_INDEPENDENT_CODE), then we need to enable it for any of
the objects in the libjpeg-turbo shared libraries.  Ideally, however, we
don't want to enable PIC for any of the objects in the libjpeg-turbo
static libraries, unless CMAKE_POSITION_INDEPENDENT_CODE is set.  Thus,
we need to build separate static and shared jpeg12 and jpeg16 object
libraries.

Fixes #684
2023-04-03 17:44:01 -05:00
DRC
0d20aa15ce TJBench: Require known subsamp type w/tiled decomp
(oversight from 386ec0abc7)

Tiled decompression will ultimately fail if the subsampling type of the
JPEG input image is unknown, but the C version of TJBench needs to fail
earlier in order to avoid using -1 (TJSAMP_UNKNOWN) as an array index
for tjMCUWidth[]/tjMCUHeight[].  The Java version now fails earlier as
well, although there is no benefit to that other than making the error
message less cryptic.
2023-03-31 11:06:52 -05:00
DRC
bc087d6aa9 TJBench: w/JPEG input imgs, set min tile= MCU size
When -tile is used with a JPEG input image, TJBench generates the tiles
using lossless cropping, which will fail if the cropping region doesn't
align with an MCU boundary.  Furthermore, there is no reason to avoid
8x8 tiles when decompressing 4:4:4 or grayscale JPEG images.
2023-03-13 17:50:38 -05:00
DRC
7313fe5aea Bump version to 2.1.6 to prepare for new commits 2023-03-13 17:49:43 -05:00
DRC
cc8c6d3667 tjbenchtest: Test all subsampling types 2023-03-13 17:36:59 -05:00
DRC
9d2f189c29 TJBench: Change subsamp for transposed 4:*:1 img
If we have transformed a 4:1:1 or 4:4:1 JPEG input image in such a way
that the horizontal and vertical dimensions are transposed, then we need
to change the subsampling type that is passed to the decomp() function.
Otherwise, tj3YUVBufSize() may return an incorrect value.

(oversight from fc881ebb21)
2023-03-13 17:36:53 -05:00
DRC
386ec0abc7 TJBench: w/JPEG input imgs, set min tile= MCU size
When -tile is used with a JPEG input image, TJBench generates the tiles
using lossless cropping, which will fail if the cropping region doesn't
align with an MCU boundary.  Furthermore, there is no reason to avoid
8x8 tiles when decompressing 4:4:4 or grayscale JPEG images.
2023-03-13 13:27:10 -05:00
DRC
fc881ebb21 TurboJPEG: Implement 4:4:1 chrominance subsampling
This allows losslessly transposed or rotated 4:1:1 JPEG images to be
losslessly cropped, partially decompressed, or decompressed to planar
YUV images.

Because tj3Transform() allows multiple lossless transformations to be
chained together, all subsampling options need to have a corresponding
transposed subsampling option.  (This is why 4:4:0 was originally
implemented as well.)  Otherwise, the documentation would be technically
incorrect.  It says that images with unknown subsampling types cannot be
losslessly cropped, partially decompressed, or decompressed to planar
YUV images, but it doesn't say anything about images with known
subsampling types whose subsampling type becomes unknown if the image is
rotated or transposed.  This is one of those situations in which it is
easier to implement a feature that works around the problem than to
document the problem.

Closes #659
2023-03-10 10:46:14 -06:00
DRC
58a3427ffc Bump version to 2.1.92 to prepare for new commits 2023-03-10 09:31:00 -06:00
DRC
0827eaff11 ChangeLog.md: Add literal vers # to 3.0 beta2 hdr
(per our convention)
2023-03-10 09:30:05 -06:00
DRC
9c432a4d40 GitHub: Add pull request template 2023-02-23 12:03:27 -06:00
DRC
c8a20e0c2f Build: Clarify CMAKE_OSX_ARCHITECTURES error
It's not that the build system doesn't support multiple values in
CMAKE_OSX_ARCHITECTURES.  It's that libjpeg-turbo, because of its SIMD
extensions, *cannot* support multiple values in CMAKE_OSX_ARCHITECTURES.
2023-02-23 12:03:06 -06:00
DRC
97df8ea9ed GitHub: Add pull request template 2023-02-23 11:57:25 -06:00
DRC
c13fe15955 Build: Clarify CMAKE_OSX_ARCHITECTURES error
It's not that the build system doesn't support multiple values in
CMAKE_OSX_ARCHITECTURES.  It's that libjpeg-turbo, because of its SIMD
extensions, *cannot* support multiple values in CMAKE_OSX_ARCHITECTURES.
2023-02-23 09:40:25 -06:00
DRC
33eaf17e5b Build: Fail if included with add_subdirectory()
Even though BUILDING.md and CONTRIBUTING.md explicitly state that the
libjpeg-turbo build system does not and will not support being
integrated into downstream build systems using add_subdirectory() (see
0565548191), people continue to file bug
reports, feature requests, and pull requests regarding that (see #265,
 #637, and #653 in addition to the issues listed in
05655481917a2d2761cf2fe19b76f639b7f159ef.)  Responding to those
issues wastes our project's limited resources.  Hopefully people will
get the hint if the build system explicitly tells them that it can't be
included using add_subdirectory(), which will prompt them to read the
comments in CMakeLists.txt explaining why.  To anyone stumbling upon
this commit message, please refer to the discussions under the issues
listed above, as well as the issues listed in
0565548191.  Our project's position on
this has been stated, explained, and defended numerous times.
2023-02-10 10:49:30 -06:00
DRC
d67edaff83 Ignore 2.1.5.1 ChangeLog header w/git diff --check
(Otherwise, checkstyle flags it as a leftover conflict marker.)
2023-02-10 10:49:10 -06:00
DRC
2af984fdae Build: Fail if included with add_subdirectory()
Even though BUILDING.md and CONTRIBUTING.md explicitly state that the
libjpeg-turbo build system does not and will not support being
integrated into downstream build systems using add_subdirectory() (see
0565548191), people continue to file bug
reports, feature requests, and pull requests regarding that (see #265,
 #637, and #653 in addition to the issues listed in
05655481917a2d2761cf2fe19b76f639b7f159ef.)  Responding to those
issues wastes our project's limited resources.  Hopefully people will
get the hint if the build system explicitly tells them that it can't be
included using add_subdirectory(), which will prompt them to read the
comments in CMakeLists.txt explaining why.  To anyone stumbling upon
this commit message, please refer to the discussions under the issues
listed above, as well as the issues listed in
0565548191.  Our project's position on
this has been stated, explained, and defended numerous times.
2023-02-10 10:48:35 -06:00
DRC
6c61033349 ChangeLog.md: Document 4e028ecd
+ bump version to 3.0 beta2
2023-02-08 10:14:04 -06:00
DRC
8ecba3647e ChangeLog.md: Document d743a2c1
+ bump version to 2.1.5.1
2023-02-08 09:29:21 -06:00
DRC
6316d4d752 OSS-Fuzz: Bail out immediately on decomp failure
Don't keep trying to decompress the same image if tj3Decompress*() has
already thrown an error.  Otherwise, if the image has an excessive
number of scans, then each iteration of the loop will try to decompress
up to the scan limit, which may cause the overall test to time out even
if one iteration doesn't time out.
2023-02-07 13:34:34 -06:00
DRC
2a5a3c6f0a OSS-Fuzz: Bail out immediately on decomp failure
Don't keep trying to decompress the same image if tj3Decompress*() has
already thrown an error.  Otherwise, if the image has an excessive
number of scans, then each iteration of the loop will try to decompress
up to the scan limit, which may cause the overall test to time out even
if one iteration doesn't time out.
2023-02-07 13:21:08 -06:00
Kornel
af265e7562 Merge tag '2.1.5'
* tag '2.1.5': (41 commits)
  BUILDING.md: Specify install prefix for MinGW/Un*x
  Java: Guard against int overflow in size methods
  turbojpeg.c: Fix UBSan warning
  tjPlane*(): Guard against int overflow
  Java doc: TJ.pixelSize --> TJ.getPixelSize()
  TJBench: Unset TJ*OPT_CROP when disabling tiling
  TJExample: Remove "underlying codec" references
  GitHub: Update to actions/checkout@v3
  TJBench: Set TJ*OPT_PROGRESSIVE with -progressive
  TJBench/Java: Fix parsing of quality ranges
  TJBench: Strictly check all non-boolean arguments
  TurboJPEG: More documentation improvements
  TJDecompressor.java: Exception message tweak
  12-bit: Set alpha channel to 4095 rather than 255
  TJDecompressor.java: "YUV" = "planar YUV"
  Java: Don't allow int overflow in buf size methods
  tjDecompressToYUV2: Use scaled dims for plane calc
  TurboJPEG: Numerous documentation improvements
  TurboJPEG: Don't use backward compatibility macros
  TurboJPEG: Ensure 'pad' arg is a power of 2
  ...
2023-02-03 20:54:24 +00:00
DRC
d743a2c12e SIMD/x86: Initialize simd_support before every use
As long as a libjpeg instance is only used by one thread at a time, a
program is technically within its rights to call jpeg_start_*compress()
in one thread and jpeg_(read|write)_*(), with the same libjpeg instance,
in a second thread.  However, because the various jsimd_can*() functions
are called within the body of jpeg_start_*compress() and simd_support is
now thread-local (due to f579cc11b3), that
led to a situation in which simd_support was initialized in the first
thread but not the second.  The uninitialized value of simd_support is
0xFFFFFFFF, which the second thread interpreted to mean that it could
use any instruction set, and when it attempted to use AVX2 instructions
on a CPU that didn't support them, an illegal instruction error
occurred.

This issue was known to affect libvips.

This commit modifies the i386 and x86-64 SIMD dispatchers so that the
various jsimd_*() functions always call init_simd(), if simd_support is
uninitialized, prior to dispatching based on the value of simd_support.
Note that the other SIMD dispatchers don't need this, because only the
x86 SIMD extensions currently support multiple instruction sets.

This patch has been verified to be performance-neutral to within
+/- 0.4% with 32-bit and 64-bit code running on a 2.8 GHz Intel Xeon
W3530 and a 3.6 GHz Intel Xeon W2123.

Fixes #649
2023-02-02 10:46:57 -06:00
DRC
4e028ecd63 SIMD/x86: Initialize simd_support before every use
As long as a libjpeg instance is only used by one thread at a time, a
program is technically within its rights to call jpeg_start_*compress()
in one thread and jpeg_(read|write)_*(), with the same libjpeg instance,
in a second thread.  However, because the various jsimd_can*() functions
are called within the body of jpeg_start_*compress() and simd_support is
now thread-local (due to f579cc11b3), that
led to a situation in which simd_support was initialized in the first
thread but not the second.  The uninitialized value of simd_support is
0xFFFFFFFF, which the second thread interpreted to mean that it could
use any instruction set, and when it attempted to use AVX2 instructions
on a CPU that didn't support them, an illegal instruction error
occurred.

This issue was known to affect libvips.

This commit modifies the i386 and x86-64 SIMD dispatchers so that the
various jsimd_*() functions always call init_simd(), if simd_support is
uninitialized, prior to dispatching based on the value of simd_support.
Note that the other SIMD dispatchers don't need this, because only the
x86 SIMD extensions currently support multiple instruction sets.

This patch has been verified to be performance-neutral to within
+/- 0.4% with 32-bit and 64-bit code running on a 2.8 GHz Intel Xeon
W3530 and a 3.6 GHz Intel Xeon W2123.

Fixes #649
2023-02-02 10:23:41 -06:00
DRC
89ceac8c85 Decompress fuzzer: Fix uninitialized memory access
(regression introduced by fc01f4673b)

Oops.  In the process of migrating the fuzzers to the TurboJPEG 3 API,
I accidentally left out the code in decompress.cc that updates the width
and height based on the scaling factor (but I apparently included that
code in decompress_yuv.cc.)

Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=55573
2023-02-01 12:31:58 -06:00
DRC
a93f6a7a63 Build: Define THREAD_LOCAL even if !WITH_TURBOJPEG
The SIMD dispatchers use thread-local storage now as well, because of
f579cc11b3.
2023-02-01 11:58:30 -06:00
DRC
dd89ce6cd6 Build: Define THREAD_LOCAL even if !WITH_TURBOJPEG
The SIMD dispatchers use thread-local storage now as well, because of
f579cc11b3.
2023-02-01 11:54:09 -06:00
DRC
fd93d98a95 Fix i386 transform fuzzer build
Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=55447
2023-01-28 12:13:32 -06:00
DRC
0205c6e04c tjbench.c: Remove vestigial int overflow checks
Since tj3Alloc() now accepts a size_t argument rather than an int
argument, it is no longer necessary to check for signed integer overflow
in the C version of TJBench.
2023-01-28 12:10:48 -06:00
DRC
6c5caf30e2 Merge branch 'main' into dev 2023-01-27 18:30:11 -06:00
DRC
3b19db4e6e BUILDING.md: Specify install prefix for MinGW/Un*x
The default install prefix when building under MinGW is chosen based on
the needs of the official build system, which uses MSYS2 to generate
Windows installer packages that install under c:\libjpeg-turbo-gcc[64].
However, attempting to configure the build with that install prefix on
a Un*x machine causes a CMake error.

Fixes #641
2023-01-27 18:24:41 -06:00
DRC
427c304595 tjbench.c: Fix Windows build error
(regression introduced by d7790789a6)
2023-01-27 14:31:48 -06:00
DRC
fd8c4da0ac Bump revision to 2.1.90 to prepare for beta
+ acknowledge upcoming 2.1.5 release
2023-01-27 14:05:07 -06:00
DRC
9b3a8f3641 jcapimin.c: Revert changes made in fc01f467
Those changes worked around an innocuous UBSan warning that was
exposed by the new TurboJPEG 3 transform fuzz target, due to the fact
that tj3Transform() no longer rejects images with unknown subsampling
configurations.  That UBSan warning was a false positive, and attempting
to fix it introduced a buffer overrun triggered by a malformed input
image that causes jpeg_write_marker() to be called with datalen == 0.  I
suspect that the UBSan false positive was only reproducible on my local
machine, but I guess we'll see.

Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=55413
2023-01-27 13:52:26 -06:00
DRC
d0015876ec Fix build if [CD]_LOSSLESS_SUPPORTED undefined
(regression introduced by fc01f4673b)
2023-01-27 13:38:00 -06:00
DRC
d7790789a6 tjbench.c: Clean up THROW_TJ*() macro usage
- Don't report which function was being called when a TurboJPEG error
  occurred, because the TurboJPEG error message already contains that
  information.

- Use THROW_TJG() for functions that report errors globally instead of
  through an instance handle.

- Use THROW_TJ() for the image I/O functions.

- Formatting tweaks
2023-01-27 13:37:55 -06:00
DRC
54f571f8fb TurboJPEG: Clean up/repurpose THROWI() macro
We already had a use case for two integer arguments, and the new use
cases benefit from two integer arguments as well.
2023-01-27 12:31:44 -06:00
DRC
8c57aad0a3 turbojpeg.c: Use THROWG() macro whenever possible 2023-01-27 12:19:16 -06:00
DRC
b94041390c TurboJPEG: Robustify JPEG header prefetching
In decompression and transform functions, use the libjpeg API state
rather than a TurboJPEG instance variable to determine whether
jpeg_mem_src_tj() and jpeg_read_header() have already been called by a
wrapper function.
2023-01-27 11:58:01 -06:00
DRC
db9f297f1c ChangeLog.md: Document TurboJPEG 3 API overhaul 2023-01-27 07:10:49 -06:00
DRC
96bc40c1b3 Implement arithmetic coding with 12-bit precision
This actually works and apparently always has worked.  It only failed
because the libjpeg code, which did not originally support arithmetic
coding, assumed that optimize_coding should always be TRUE for 12-bit
data precision.
2023-01-26 13:11:58 -06:00
DRC
fc01f4673b TurboJPEG 3 API overhaul
(ChangeLog update forthcoming)

- Prefix all function names with "tj3" and remove version suffixes from
  function names.  (Future API overhauls will increment the prefix to
  "tj4", etc., thus retaining backward API/ABI compatibility without
  versioning each individual function.)

- Replace stateless boolean flags (including TJ*FLAG_ARITHMETIC and
  TJ*FLAG_LOSSLESS, which were never released) with stateful integer
  parameters, the value of which persists between function calls.
  * Use parameters for the JPEG quality and subsampling as well, in
    order to eliminate the awkwardness of specifying function arguments
    that weren't relevant for lossless compression.
  * tj3DecompressHeader() now stores all relevant information about the
    JPEG image, including the width, height, subsampling type, entropy
    coding type, etc. in parameters rather than returning that
    information in its arguments.
  * TJ*FLAG_LIMITSCANS has been reimplemented as an integer parameter
    (TJ*PARAM_SCANLIMIT) that allows the number of scans to be
    specified.

- Use the const keyword for all pointer arguments to unmodified
  buffers, as well as for both dimensions of 2D pointers.  Addresses
  #395.

- Use size_t rather than unsigned long to represent buffer sizes, since
  unsigned long is a 32-bit type on Windows.  Addresses #24.

- Return 0 from all buffer size functions if an error occurs, rather
  than awkwardly trying to return -1 in an unsigned data type.

- Implement 12-bit and 16-bit data precision using dedicated
  compression, decompression, and image I/O functions/methods.
  * Suffix the names of all data-precision-specific functions with 8,
    12, or 16.
  * Because the YUV functions are intended to be used for video, they
    are currently only implemented with 8-bit data precision, but they
    can be expanded to 12-bit data precision in the future, if
    necessary.
  * Extend TJUnitTest and TJBench to test 12-bit and 16-bit data
    precision, using a new -precision option.
  * Add appropriate regression tests for all of the above to the 'test'
    target.
  * Extend tjbenchtest to test 12-bit and 16-bit data precision, and
    add separate 'tjtest12' and 'tjtest16' targets.
  * BufferedImage I/O in the Java API is currently limited to 8-bit
    data precision, since the BufferedImage class does not
    straightforwardly support higher data precisions.
  * Extend the PPM reader to convert 12-bit and 16-bit PBMPLUS files
    to grayscale or CMYK pixels, as it already does for 8-bit files.

- Properly accommodate lossless JPEG using dedicated parameters
  (TJ*PARAM_LOSSLESS, TJ*PARAM_LOSSLESSPSV, and TJ*PARAM_LOSSLESSPT),
  rather than using a flag and awkwardly repurposing the JPEG quality.
  Update TJBench to properly reflect whether a JPEG image is lossless.

- Re-organize the TJBench usage screen.

- Update the Java docs using Java 11, to improve the formatting and
  eliminate HTML frames.

- Use the accurate integer DCT algorithm by default for both
  compression and decompression, since the "fast" algorithm is a legacy
  feature, it does not pass the ISO compliance tests, and it is not
  actually faster on modern x86 CPUs.
  * Remove the -accuratedct option from TJBench and TJExample.

- Re-implement the 'tjtest' target using a CMake script that enables
  the appropriate tests, depending on the data precision and whether or
  not the Java API is part of the build.

- Consolidate the C and Java versions of tjbenchtest into one script.

- Consolidate the C and Java versions of tjexampletest into one script.

- Combine all initialization functions into a single function
  (tj3Init()) that accepts an integer parameter specifying the
  subsystems to initialize.

- Enable decompression scaling explicitly, using a new function/method
  (tj3SetScalingFactor()/TJDecompressor.setScalingFactor()), rather
  than implicitly using awkward "desired width"/"desired height"
  parameters.

- Introduce a new macro/constant (TJUNSCALED/TJ.UNSCALED) that maps to
  a scaling factor of 1/1.

- Implement partial image decompression, using a new function/method
  (tj3SetCroppingRegion()/TJDecompressor.setCroppingRegion()) and
  TJBench option (-crop).  Extend tjbenchtest to test the new feature.
  Addresses #1.

- Allow the JPEG colorspace to be specified explicitly when
  compressing, using a new parameter (TJ*PARAM_COLORSPACE).  This
  allows JPEG images with the RGB and CMYK colorspaces to be created.

- Remove the error/difference image feature from TJBench.  Identical
  images to the ones that TJBench created can be generated using
  ImageMagick with
  'magick composite <original_image> <output_image> -compose difference <diff_image>'

- Handle JPEG images with unknown subsampling types.  TJ*PARAM_SUBSAMP
  is set to TJ*SAMP_UNKNOWN (== -1) for such images, but they can still
  be decompressed fully into packed-pixel images or losslessly
  transformed (with the exception of lossless cropping.)  They cannot
  be partially decompressed or decompressed into planar YUV images.
  Note also that TJBench, due to its lack of support for imperfect
  transforms, requires that the subsampling type be known when
  rotating, flipping, or transversely transposing an image.  Addresses
  #436

- The Java version of TJBench now has identical functionality to the C
  version.  This was accomplished by (somewhat hackishly) calling the
  TurboJPEG C image I/O functions through JNI and copying the pixels
  between the C heap and the Java heap.

- Add parameters (TJ*PARAM_RESTARTROWS and TJ*PARAM_RESTARTBLOCKS) and
  a TJBench option (-restart) to allow the restart marker interval to
  be specified when compressing.  Eliminate the undocumented TJ_RESTART
  environment variable.

- Add a parameter (TJ*PARAM_OPTIMIZE), a transform option
  (TJ*OPT_OPTIMIZE), and a TJBench option (-optimize) to allow
  optimized baseline Huffman coding to be specified when compressing.
  Eliminate the undocumented TJ_OPTIMIZE environment variable.

- Add parameters (TJ*PARAM_XDENSITY, TJ*PARAM_DENSITY, and
  TJ*DENSITYUNITS) to allow the pixel density to be specified when
  compressing or saving a Windows BMP image and to be queried when
  decompressing or loading a Windows BMP image.  Addresses #77.

- Refactor the fuzz targets to use the new API.
  * Extend decompression coverage to 12-bit and 16-bit data precision.
  * Replace the awkward cjpeg12 and cjpeg16 targets with proper
    TurboJPEG-based compress12, compress12-lossless, and
    compress16-lossless targets

- Fix innocuous UBSan warnings uncovered by the new fuzzers.

- Implement previous versions of the TurboJPEG API by wrapping the new
  functions (tested by running the 2.1.x versions of TJBench, via
  tjbenchtest, and TJUnitTest against the new implementation.)
  * Remove all JNI functions for deprecated Java methods and implement
    the deprecated methods using pure Java wrappers.  It should be
    understood that backward API compatibility in Java applies only to
    the Java classes and that one cannot mix and match a JAR file from
    one version of libjpeg-turbo with a JNI library from another
    version.

- tj3Destroy() now silently accepts a NULL handle.

- tj3Alloc() and tj3Free() now return/accept void pointers, as malloc()
  and free() do.

- The image I/O functions now accept a TurboJPEG instance handle, which
  is used to transmit/receive parameters and to receive error
  information.

Closes #517
2023-01-25 19:09:34 -06:00
DRC
1a1ea4eeba Merge branch 'main' into dev 2023-01-25 12:28:42 -06:00
DRC
27f4ff80ce Java: Guard against int overflow in size methods
Because Java array sizes are ints, the various size methods in the TJ
class have int return values.  Thus, we have to guard against signed
int overflow at the JNI level, because the C functions can return sizes
greater than INT_MAX.

This also adds a test for TJ.planeWidth() and TJ.planeHeight(), in order
to validate 8a1526a442 in Java.
2023-01-25 12:21:35 -06:00
DRC
1485beaa49 turbojpeg.c: Fix UBSan warning
(introduced by previous commit)
2023-01-25 12:14:14 -06:00
DRC
8a1526a442 tjPlane*(): Guard against int overflow
tjPlaneWidth() and tjPlaneHeight() could overflow a signed int and
return a negative value if passed a width/height argument of INT_MAX and
a subsampling type for which the MCU block size is larger than 8x8.
2023-01-25 10:00:07 -06:00
DRC
52659f4f47 Merge branch 'main' into dev 2023-01-23 09:55:13 -06:00
DRC
edbb7e6d43 Java doc: TJ.pixelSize --> TJ.getPixelSize()
TJ.pixelSize isn't actually a thing.  Oops.
2023-01-23 09:50:29 -06:00
DRC
af1b4c8df4 TJBench: Unset TJ*OPT_CROP when disabling tiling
Otherwise, if the input image is a JPEG image, then an unnecessary
lossless transformation will be performed.
2023-01-21 18:31:20 -06:00
DRC
2aac545899 TJExample: Remove "underlying codec" references
(Oversight from 9a146f0f23)
2023-01-20 16:06:57 -06:00
DRC
7ab6222cff Merge branch 'main' into dev 2023-01-20 14:09:25 -06:00
DRC
0738305ec5 GitHub: Update to actions/checkout@v3
... to silence deprecation warning regarding Node.js 12 actions.
2023-01-20 13:41:25 -06:00
DRC
98a6455875 TJBench: Set TJ*OPT_PROGRESSIVE with -progressive
The documented behavior of the -progressive option is to use progressive
entropy coding in JPEG images generated by compression and transform
operations.  However, setting TJFLAG_PROGRESSIVE was insufficient to
accomplish that, because TJBench doesn't enable lossless transformation
if xformOpt == 0.
2023-01-20 13:23:00 -06:00
DRC
b99e7590b0 TJBench/Java: Fix parsing of quality ranges 2023-01-20 13:02:38 -06:00
DRC
28c2e60770 TJBench: Strictly check all non-boolean arguments
+ document that the value of -yuvpad must be a power of 2 (refer to
d260858395)
2023-01-20 13:02:38 -06:00
DRC
fb15efe94f TurboJPEG: More documentation improvements
- TJBench/TJUnitTest: Wordsmith command-line output

- Java: "decompress operations"="decompression operations"

- tjLoadImage(): Error message tweak

- Don't mention compression performance in the description of
  TJXOPT_PROGRESSIVE/TJTransform.OPT_PROGRESSIVE, because the image has
  already been compressed at that point.

(Oversights from 9a146f0f23)
2023-01-20 12:50:21 -06:00
DRC
6a060d8c95 TJCompressor.java: (C) header formatting tweak
(apparently borked by one of the previous merge commits)
2023-01-17 18:32:15 -06:00
DRC
c7c02d9288 Merge branch 'main' into dev 2023-01-17 18:31:31 -06:00
DRC
7ed186ed79 TJDecompressor.java: Exception message tweak
NO_ASSOC_ERROR is specific to JPEG source images, but the decompress()
methods can handle YUV source images as well.
2023-01-17 18:18:27 -06:00
DRC
08cbc23334 12-bit: Set alpha channel to 4095 rather than 255 2023-01-17 15:29:02 -06:00
DRC
155a8b0321 Merge branch 'main' into dev 2023-01-16 17:02:01 -06:00
DRC
0c0df2d0c7 TJDecompressor.java: "YUV" = "planar YUV"
(Oversight from 9a146f0f23)
2023-01-16 16:54:08 -06:00
DRC
22a6636852 Java: Don't allow int overflow in buf size methods
This is similar to the fix that 2a9e3bd743
applied to the C API.  We have to apply it separately at the JNI level
because the Java API always stores buffer sizes in 32-bit integers, and
the C buffer size functions could overflow an int when using 64-bit
code.  (NOTE: The Java API stores buffer sizes in 32-bit integers
because Java itself always uses 32-bit integers for array sizes.)  Since
Java don't allow no buffer overruns 'round here, this commit doesn't
change the ultimate outcome.  It just makes the inevitable exception
easier to diagnose.
2023-01-16 16:48:40 -06:00
DRC
d859232da3 TurboJPEG: Use 4:4:4 for lossless JPEG buf calcs 2023-01-14 18:27:37 -06:00
DRC
d4589f4f1c Merge branch 'main' into dev 2023-01-14 18:07:53 -06:00
DRC
94a2b95342 tjDecompressToYUV2: Use scaled dims for plane calc
The documented behavior of the function is to use decompression scaling
to generate the largest possible image that will fit within the desired
image dimensions.  Thus, if the desired image dimensions are larger than
the scaled image dimensions, then tjDecompressToYUV2() should use the
scaled image dimensions when computing the plane pointers and strides to
pass to tjDecompressToYUVPlanes().

Note that this bug was not previously detected, because tjunittest and
tjbench always passed the scaled image dimensions to
tjDecompressToYUV2().
2023-01-14 17:26:17 -06:00
DRC
9a146f0f23 TurboJPEG: Numerous documentation improvements
- Wordsmithing, formatting, and grammar tweaks

- Various clarifications and corrections, including specifying whether
  a particular buffer or image is used as a source or destination

- Accommodate/mention features that were introduced since the API
  documentation was created.

- For clarity, use "packed-pixel" to describe uncompressed
  source/destination images that are not planar YUV.

- Use "row" rather than "line" to refer to a single horizontal group of
  pixels or component values, for consistency with the libjpeg API
  documentation.  (libjpeg also uses "scanline", which is a more archaic
  term.)

- Use "alignment" rather than "padding" to refer to the number of bytes
  by which a row's width is evenly divisible.  This consistifies the
  documention of the YUV functions and tjLoadImage().  ("Padding"
  typically refers to the number of bytes added to each row, which is
  not the same thing.)

- Remove all references to "the underlying codec."  Although the
  TurboJPEG API originated as a cross-platform wrapper for the Intel
  Integrated Performance Primitives, Sun mediaLib, QuickTime, and
  libjpeg, none of those TurboJPEG implementations has been maintained
  since 2009.  Nothing would prevent someone from implementing the
  TurboJPEG API without libjpeg-turbo, but such an implementation would
  not necessarily have an "underlying codec."  (It could be fully
  self-contained.)

- Use "destination image" rather than "output image", for consistency,
  or describe the type of image that will be output.

- Avoid the term "image buffer" and instead use "byte buffer" to
  refer to buffers that will hold JPEG images, or describe the type of
  image that will be contained in the buffer.  (The Java documentation
  doesn't use "byte buffer", because the buffer arrays literally have
  "byte" in front of them, and since Java doesn't have pointers, it is
  not possible for mere mortals to store any other type of data in those
  arrays.)

- C: Use "unified" to describe YUV images stored in a single buffer, for
  consistency with the Java documentation.

- Use "planar YUV" rather than "YUV planar".  Is is our convention to
  describe images using {component layout} {colorspace/pixel format}
  {image function}, e.g. "packed-pixel RGB source image" or "planar YUV
  destination image."

- C: Document the TurboJPEG API version in which a particular function
  or macro was introduced, and reorder the backward compatibility
  function stubs in turbojpeg.h alphabetically by API version.

- C: Use Markdown rather than HTML tags, where possible, in the Doxygen
  comments.
2023-01-14 17:10:31 -06:00
DRC
b03ee8b835 TurboJPEG: Don't use backward compatibility macros
Macros from older versions of the TurboJPEG API are supported but not
documented, so using the current version of those macros makes the code
more readable.
2023-01-05 14:26:36 -06:00
DRC
d260858395 TurboJPEG: Ensure 'pad' arg is a power of 2
Because the PAD() macro can only handle powers of 2, this is a necessary
restriction (and a documented one, except in the case of
tjCompressFromYUV()-- oops.)  Failing to check the 'pad' argument
caused tjBufSizeYUV2() to return bogus results if 'pad' was less than 1
or otherwise not a power of 2.  tjEncodeYUV3() and tjDecodeYUV()
effectively treated a 'pad' value of 0 as unpadded, but that was subtle
and undocumented behavior.  tjCompressFromYUV() did not check whether
'pad' was a power of 2, so the strides passed to
tjCompressFromYUVPlanes() would have been incorrect if 'pad' was not a
power of 2.  That would not have caused tjCompressFromYUV() to overrun
the source buffer, as long as the calling application allocated the
buffer based on the return value of tjBufSizeYUV2() (which computes the
strides in the same manner as tjCompressFromYUV().)  However, if the
calling application attempted to initialize the source buffer using
correctly-computed strides, then it could have overrun its own
buffer in certain cases or produced incorrect JPEG images in others.

Realistically, there is no reason why an application would want to pass
a non-power-of-2 'pad' value to a TurboJPEG API function, so this commit
is about user-proofing the API rather than fixing any known issue.
2023-01-05 14:22:17 -06:00
DRC
0e63514214 Decomp: Fix color quant w/ 16-bit lossless JPEGs
(oversight from 2241434eb9)

This fixes segfaults and other issues that occurred when attempting to
decompress a 16-bit lossless JPEG image using color quantization
(which is used when decompressing to a GIF image.)
2022-12-21 16:51:22 -06:00
DRC
d6d6ac739f Win: Add jpeg16* functions to DLL module def files
(oversight from previous commit)
2022-12-16 14:15:02 -06:00
DRC
2241434eb9 16-bit lossless JPEG support 2022-12-16 13:57:03 -06:00
DRC
ad4e2ad86f CONTRIBUTING.md: Include lossless JPEG in policy 2022-12-07 16:01:55 -06:00
DRC
803523402f Merge branch 'main' into dev 2022-12-07 14:11:37 -06:00
DRC
dc4a93fab3 jpegtran: Fix FPE w/ -drop & -trim on corrupt JPEG
requant_comp() in transupp.c, a function that supports the jpegtran
-drop option, borrows code from the C quantization function in order to
re-quantize the coefficients from the dropped image.  However, the
function does not guard against the possibility that a corrupt source
image could inject quantization table values equal to 0, thus causing a
divide-by-zero error.  Since this error affected only jpegtran and not
any of the libraries (the tjTransform() function in the TurboJPEG API
does not expose the image drop feature), it did not represent a security
risk.  In fact, this commit does not change the output of jpegtran when
attempting to transform the aforementioned corrupt source image.  It
merely eliminates the floating point exception.  Like most issues of
this type, however, eliminating the error prevents it from hiding
legitimate security issues that may later be introduced.

Fixes #635
Fixes #636
2022-12-07 14:01:40 -06:00
DRC
5da86f7430 ChangeLog.md: List CVE ID fixed by 9120a247 2022-12-07 09:45:57 -06:00
DRC
7bb5cb560e ChangeLog.md: List CVE ID fixed by f35fd27e 2022-12-07 09:39:03 -06:00
DRC
0f047a5747 Merge branch 'main' into dev 2022-11-30 18:45:50 -06:00
DRC
7f2eb09d6e BUILDING.md: Add Arm64 iOS sim build instructions
Unfortunately, iOS builds cannot be used with the iOS simulator on Macs
with Apple silicon CPUs.  Even more unfortunately, universal binaries
can only have one slice for each CPU architecture, so it would not be
possible to add a dedicated Arm64 iOS simulator slice to the existing
libjpeg-turbo iOS binaries.  (It would be necessary to release a
separate package solely for the iOS simulator.)  Because the Arm Neon
SIMD extensions for libjpeg-turbo now use compiler intrinsics when
building with Xcode, it is easy to build libjpeg-turbo from source when
targeting Arm64-based Apple platforms.  Thus, for the moment, I have
chosen to document how to avoid the pothole rather than to fill it in.
2022-11-30 18:44:45 -06:00
DRC
e2a98701e4 turbojpeg.c: Fix build if !C_LOSSLESS_SUPPORTED 2022-11-30 11:06:37 -06:00
DRC
73ca9712e3 Merge branch 'main' into dev 2022-11-30 11:03:43 -06:00
DRC
403cfad611 djpeg.c: Fix build if !SAVE_MARKERS_SUPPORTED 2022-11-30 10:43:29 -06:00
DRC
c4105ba7ef turbojpeg.c: Fix build if !C_PROGRESSIVE_SUPPORTED 2022-11-30 10:41:32 -06:00
DRC
e7a248ebb7 Merge branch 'main' into dev 2022-11-29 01:08:27 -06:00
DRC
45cd2ded88 12-bit: Prevent RGB-to-YCC table overrun/underrun
cjpeg relies on the various file I/O modules to range-limit the input
samples, but no range limiting is performed by the
jpeg_write_scanlines() function itself.  With 8-bit samples, that isn't
a problem, because sample values > MAXJSAMPLE will overflow the data
type and wrap around to 0.  With 12-bit samples, however, it is possible
to pass sample values < 0 or > 4095 to jpeg_write_scanlines(), which
would cause the RGB-to-YCbCr color converter to underflow or overflow
the RGB-to-YCbCr conversion tables.  That issue has existed in libjpeg
all along.  This commit mitigates the issue by masking off all but the
lowest 12 bits of each 12-bit input sample prior to using the input
sample value to index the RGB-to-YCbCr conversion tables.

Fixes #633
2022-11-29 00:53:55 -06:00
DRC
8b9bc4b963 jconfig.h: Restore BITS_IN_JSAMPLE macro
Because of e8b40f3c2b, we now support
multiple data precisions in the same libjpeg API library, so
BITS_IN_JSAMPLE is no longer used to specify the data precision at build
time.  However, some downstream software expects the macro to be
defined.  Since 12-bit data precision is an opt-in feature that requires
explicitly calling 12-bit-specific libjpeg API functions and using
12-bit-specific data types, the unmodified portion of the libjpeg API
still behaves as if it were built for 8-bit precision, and JSAMPLE is
still literally an 8-bit data type.  Thus, it is correct to externally
define BITS_IN_JSAMPLE to 8 in jconfig.h.  Since the build system also
uses BITS_IN_JSAMPLE internally to build both 8-bit and 12-bit versions
of relevant modules, the definition of BITS_IN_JSAMPLE in jconfig.h is
now guarded by #ifndef BITS_IN_JSAMPLE.  (Hopefully that doesn't cause
any problems.)

Fixes #632
2022-11-23 16:35:58 -06:00
DRC
4afa4d3ee8 jconfig.h: Restore MEM_SRCDST_SUPPORTED macro
That macro has been defined in jconfig.h since libjpeg-turbo 1.3.x, so
it is possible that some downstream software conditions the use of the
jpeg_mem_*() functions on whether MEM_SRCDST_SUPPORTED is defined or
JPEG_LIB_VERSION >= 80 (as libjpeg-turbo 2.1.x and prior did
internally.)
2022-11-23 16:35:54 -06:00
DRC
140a1ea315 tjEncodeYUVPlanes(): Ignore TJFLAG_LOSSLESS
TJFLAG_LOSSLESS is irrelevant to planar YUV encoding, and setting the
flag caused tjEncode*() to fail with "Invalid lossless parameters"
because tjEncodeYUVPlanes() passes a JPEG quality value of -1 to
setCompDefaults().  This commit modifies setCompDefaults() so that it
takes no action related to the jpegQual parameter unless jpegQual >= 0.
2022-11-22 10:47:44 -06:00
DRC
382563a58c Build: Add missing tjbenchtest -arithmetic tests
... if WITH_JAVA=0.

(Oversight from 6002720c37)
2022-11-21 22:46:30 -06:00
DRC
98ff1fd103 TurboJPEG: Add lossless JPEG detection capability
Add a new TurboJPEG C API function (tjDecompressHeader4()) and Java API
method (TJDecompressor.getFlags()) that return the bitwise OR of any
flags that are relevant to the JPEG image being decompressed (currently
TJFLAG_PROGRESSIVE, TJFLAG_ARITHMETIC, TJFLAG_LOSSLESS, and their Java
equivalents.)  This allows a calling program to determine whether the
image being decompressed is a lossless JPEG image, which means that the
decompression scaling feature will not be available and that a
full-sized destination buffer should be allocated.

More specifically, this fixes a buffer overrun in TJBench, TJExample,
and the decompress* fuzz targets that occurred when attempting (in vain)
to decompress a lossless JPEG image with decompression scaling enabled.
2022-11-21 22:46:12 -06:00
DRC
b85b028d2b OSS-Fuzz: Fix argument error in cjpeg12 target
Smoothing can only be used with 4:2:0 subsampling.
2022-11-21 22:42:59 -06:00
DRC
db9dd93da4 Lossless: Fix innocuous UBSan warnings 2022-11-21 22:42:59 -06:00
DRC
07129256e0 OSS-Fuzz: Add fuzz target for lossless JPEG 2022-11-21 22:42:59 -06:00
DRC
1a31176e0c Merge branch 'main' into dev 2022-11-21 22:42:46 -06:00
DRC
74d5b168f7 Build: Update tjtest target dependencies 2022-11-21 22:41:46 -06:00
DRC
25ccad99a0 TurboJPEG: 8-bit lossless JPEG support 2022-11-16 15:57:25 -06:00
DRC
3fb10c35d8 Merge branch 'ijg.lossless' into dev
Lossless: Accommodate LJT colorspace/SIMD exts

In libjpeg-turbo, grayscale_convert() and null_convert() aren't the only
lossless color conversion algorithms.  We can also losslessly convert
RGB to and from any of the extended RGB colorspaces, and some platforms
have SIMD-accelerated null color conversion.

This commit also disallows RGB565 output in lossless mode, and it moves
the IsExtRGB() macro from cdjpeg.h to jpegint.h and repurposes it to
make jinit_color_converter() and jinit_color_deconverter() more
readable.
2022-11-16 12:35:40 -06:00
DRC
af618ffe09 Clean up the lossless JPEG feature
- Rename jpeg_simple_lossless() to jpeg_enable_lossless() and modify the
  function so that it stores the lossless parameters directly in the Ss
  and Al fields of jpeg_compress_struct rather than using a scan script.

- Move the cjpeg -lossless switch into "Switches for advanced users".

- Document the libjpeg API and run-time features that are unavailable in
  lossless mode, and ensure that all parameters, functions, and switches
  related to unavailable features are ignored or generate errors in
  lossless mode.

- Defer any action that depends on whether lossless mode is enabled
  until jpeg_start_compress()/jpeg_start_decompress() is called.

- Document the purpose of the point transform value.

- "Codec" stands for coder/decoder, so it is a bit awkward to say
  "lossless compression codec" and "lossless decompression codec".
  Use "lossless compressor" and "lossless decompressor" instead.

- Restore backward API/ABI compatibility with libjpeg v6b:

  * Move the new 'lossless' field from the exposed jpeg_compress_struct
    and jpeg_decompress_struct structures into the opaque
    jpeg_comp_master and jpeg_decomp_master structures, and allocate the
    master structures in the body of jpeg_create_compress() and
    jpeg_create_decompress().

  * Remove the new 'process' field from jpeg_compress_struct and
    jpeg_decompress_struct and replace it with the old
    'progressive_mode' field and the new 'lossless' field.

  * Remove the new 'data_unit' field from jpeg_compress_struct and
    jpeg_decompress_struct and replace it with a locally-computed
    data unit variable.

  * Restore the names of macros and fields that refer to DCT blocks, and
    document that they have a different meaning in lossless mode.  (Most
    of them aren't very meaningful in lossless mode anyhow.)

  * Remove the new alloc_darray() method from jpeg_memory_mgr and
    replace it with an internal macro that wraps the alloc_sarray()
    method.

  * Move the JDIFF* data types from jpeglib.h and jmorecfg.h into
    jpegint.h.

  * Remove the new 'codec' field from jpeg_compress_struct and
    jpeg_decompress_struct and instead reuse the existing internal
    coefficient control, forward/inverse DCT, and entropy
    encoding/decoding structures for lossless compression/decompression.

  * Repurpose existing error codes rather than introducing new ones.
    (The new JERR_BAD_RESTART and JWRN_MUST_DOWNSCALE codes remain,
    although JWRN_MUST_DOWNSCALE will probably be removed in
    libjpeg-turbo, since we have a different way of handling multiple
    data precisions.)

- Automatically enable lossless mode when a scan script with parameters
  that are only valid for lossless mode is detected, and document the
  use of scan scripts to generate lossless JPEG images.

- Move the sequential and shared Huffman routines back into jchuff.c and
  jdhuff.c, and document that those routines are shared with jclhuff.c
  and jdlhuff.c as well as with jcphuff.c and jdphuff.c.

- Move MAX_DIFF_BITS from jchuff.h into jclhuff.c, the only place where
  it is used.

- Move the predictor and scaler code into jclossls.c and jdlossls.c.

- Streamline register usage in the [un]differencers (inspired by similar
  optimizations in the color [de]converters.)

- Restructure the logic in a few places to reduce duplicated code.

- Ensure that all lossless-specific code is guarded by
  C_LOSSLESS_SUPPORTED or D_LOSSLESS_SUPPORTED and that the library can
  be built successfully if either or both of those macros is undefined.

- Remove all short forms of external names introduced by the lossless
  JPEG patch.  (These will not be needed by libjpeg-turbo, so there is
  no use cleaning them up.)

- Various wordsmithing, formatting, and punctuation tweaks

- Eliminate various compiler warnings.
2022-11-16 11:27:18 -06:00
DRC
918ace631e example.c: Fix compiler warning 2022-11-16 10:36:57 -06:00
DRC
766910e8b2 Merge branch 'ijg.lossless' into dev
Fix segfault when decomp lossless JPEG w/ restarts

The predict_process_restart() method in jpeg_lossless_decompressor was
unset, because we now use the start_pass() method in jpeg_inverse_dct
instead.  Thus, a segfault occurred when attempting to decompress a
lossless JPEG that contained restart markers.
2022-11-16 01:03:15 -06:00
DRC
b56e8b28ba Clean up the lossless JPEG feature
- Rename jpeg_simple_lossless() to jpeg_enable_lossless() and modify the
  function so that it stores the lossless parameters directly in the Ss
  and Al fields of jpeg_compress_struct rather than using a scan script.

- Move the cjpeg -lossless switch into "Switches for advanced users".

- Document the libjpeg API and run-time features that are unavailable in
  lossless mode, and ensure that all parameters, functions, and switches
  related to unavailable features are ignored or generate errors in
  lossless mode.

- Defer any action that depends on whether lossless mode is enabled
  until jpeg_start_compress()/jpeg_start_decompress() is called.

- Document the purpose of the point transform value.

- "Codec" stands for coder/decoder, so it is a bit awkward to say
  "lossless compression codec" and "lossless decompression codec".
  Use "lossless compressor" and "lossless decompressor" instead.

- Restore backward API/ABI compatibility with libjpeg v6b:

  * Move the new 'lossless' field from the exposed jpeg_compress_struct
    and jpeg_decompress_struct structures into the opaque
    jpeg_comp_master and jpeg_decomp_master structures, and allocate the
    master structures in the body of jpeg_create_compress() and
    jpeg_create_decompress().

  * Remove the new 'process' field from jpeg_compress_struct and
    jpeg_decompress_struct and replace it with the old
    'progressive_mode' field and the new 'lossless' field.

  * Remove the new 'data_unit' field from jpeg_compress_struct and
    jpeg_decompress_struct and replace it with a locally-computed
    data unit variable.

  * Restore the names of macros and fields that refer to DCT blocks, and
    document that they have a different meaning in lossless mode.  (Most
    of them aren't very meaningful in lossless mode anyhow.)

  * Remove the new alloc_darray() method from jpeg_memory_mgr and
    replace it with an internal macro that wraps the alloc_sarray()
    method.

  * Move the JDIFF* data types from jpeglib.h and jmorecfg.h into
    jpegint.h.

  * Remove the new 'codec' field from jpeg_compress_struct and
    jpeg_decompress_struct and instead reuse the existing internal
    coefficient control, forward/inverse DCT, and entropy
    encoding/decoding structures for lossless compression/decompression.

  * Repurpose existing error codes rather than introducing new ones.
    (The new JERR_BAD_RESTART and JWRN_MUST_DOWNSCALE codes remain,
    although JWRN_MUST_DOWNSCALE will probably be removed in
    libjpeg-turbo, since we have a different way of handling multiple
    data precisions.)

- Automatically enable lossless mode when a scan script with parameters
  that are only valid for lossless mode is detected, and document the
  use of scan scripts to generate lossless JPEG images.

- Move the sequential and shared Huffman routines back into jchuff.c and
  jdhuff.c, and document that those routines are shared with jclhuff.c
  and jdlhuff.c as well as with jcphuff.c and jdphuff.c.

- Move MAX_DIFF_BITS from jchuff.h into jclhuff.c, the only place where
  it is used.

- Move the predictor and scaler code into jclossls.c and jdlossls.c.

- Streamline register usage in the [un]differencers (inspired by similar
  optimizations in the color [de]converters.)

- Restructure the logic in a few places to reduce duplicated code.

- Ensure that all lossless-specific code is guarded by
  C_LOSSLESS_SUPPORTED or D_LOSSLESS_SUPPORTED and that the library can
  be built successfully if either or both of those macros is undefined.

- Remove all short forms of external names introduced by the lossless
  JPEG patch.  (These will not be needed by libjpeg-turbo, so there is
  no use cleaning them up.)

- Various wordsmithing, formatting, and punctuation tweaks

- Eliminate various compiler warnings.
2022-11-16 00:49:15 -06:00
DRC
6002720c37 TurboJPEG: Opt. enable arithmetic entropy coding 2022-11-15 23:38:55 -06:00
DRC
bc086c4427 Merge branch 'main' into dev 2022-11-15 23:38:47 -06:00
DRC
eb1fd4ad34 Build: Fix typo in tjtest target 2022-11-15 23:38:19 -06:00
DRC
ed73fdc9be Merge branch 'main' into dev 2022-11-15 21:28:01 -06:00
Erin Melucci
37dd973bef Win: Use wchar_t for copyright string in RC files
llvm-rc doesn't like the copyright symbol in the LegalCopyright string.

Possible solutions:
1. Replace the copyright symbol with "(C)".
2. Prefix the string literal with L, thus making it a wide character
   string.
3. Pass -c65001 to the resource compiler to enable the UTF-8 code page.

Option 2 is the least disruptive, since it doesn't change the behavior
of the official builds or require any build system modifications.

Closes #627
2022-11-15 21:12:54 -06:00
DRC
78a36f6dc3 Fix buffer overrun in 12-bit prog Huffman encoder
Regression introduced by 16bd984557 and
5b177b3cab

The pre-computed absolute values used in encode_mcu_AC_first() and
encode_mcu_AC_refine() were stored in a JCOEF (signed short) array.
When attempting to losslessly transform a specially-crafted malformed
12-bit JPEG image with a coefficient value of -32768 into a progressive
12-bit JPEG image, the progressive Huffman encoder attempted to store
the absolute value of -32768 in the JCOEF array, thus overflowing the
16-bit signed data type.  Therefore, at this point in the code:
8c5e78ce29/jcphuff.c (L889)
the absolute value was read as -32768, which caused the test at
8c5e78ce29/jcphuff.c (L896)
to fail, falling through to
8c5e78ce29/jcphuff.c (L908)
with an overly large value of r (46) that, when shifted left four
places, incremented, and passed to emit_symbol(), exceeded the maximum
index (255) for the derived code tables.  Fortunately, the buffer
overrun was fully contained within phuff_entropy_encoder, so the issue
did not generate a segfault or other user-visible errant behavior, but
it did cause a UBSan failure that was detected by OSS-Fuzz.

This commit introduces an unsigned JCOEF (UJCOEF) data type and uses it
to store the absolute values of DCT coefficients computed by the
AC_first_prepare() and AC_refine_prepare() methods.

Note that the changes to the Arm Neon progressive Huffman encoder
extensions cause signed 16-bit instructions to be replaced with
equivalent unsigned 16-bit instructions, so the changes should be
performance-neutral.

Based on:
bbf61c0382

Closes #628
2022-11-15 19:07:50 -06:00
DRC
aa3dd0bd29 TurboJPEG: Nix unneeded setDecodeDefaults ret val
The return value was inherited from setDecompDefaults() in
34dca05227, but it was never needed.
2022-11-15 15:41:07 -06:00
DRC
1926ab4186 ChangeLog.md: Multi-precision feature wordsmithing
- Because of b5a9ef64ea, "by default" is
  no longer applicable.  (12-bit-per-component JPEG support is now part
  of the core libjpeg-turbo functionality and cannot be disabled.)

- Change awkward "can be used to enable the creation of" to less awkward
  "can be used to create".
2022-11-14 16:31:41 -06:00
DRC
99866007c6 jclhuff.c: Fix innocuous UBSan left shift warning
This applies the progressive Huffman encoder fixes from
aa769febf2 and
d65e768b2e to the new lossless mode
Huffman encoder.
2022-11-14 16:26:41 -06:00
DRC
8fc9356581 usage.txt: Move -precision into advanced switches
(to match cjpeg man page and usage screen)
2022-11-14 16:11:30 -06:00
DRC
97772cba65 Merge branch 'ijg.lossless' into dev
Refer to #402
2022-11-14 15:36:25 -06:00
DRC
217d1a75f5 Clean up the lossless JPEG feature
- Rename jpeg_simple_lossless() to jpeg_enable_lossless() and modify the
  function so that it stores the lossless parameters directly in the Ss
  and Al fields of jpeg_compress_struct rather than using a scan script.

- Move the cjpeg -lossless switch into "Switches for advanced users".

- Document the libjpeg API and run-time features that are unavailable in
  lossless mode, and ensure that all parameters, functions, and switches
  related to unavailable features are ignored or generate errors in
  lossless mode.

- Defer any action that depends on whether lossless mode is enabled
  until jpeg_start_compress()/jpeg_start_decompress() is called.

- Document the purpose of the point transform value.

- "Codec" stands for coder/decoder, so it is a bit awkward to say
  "lossless compression codec" and "lossless decompression codec".
  Use "lossless compressor" and "lossless decompressor" instead.

- Restore backward API/ABI compatibility with libjpeg v6b:

  * Move the new 'lossless' field from the exposed jpeg_compress_struct
    and jpeg_decompress_struct structures into the opaque
    jpeg_comp_master and jpeg_decomp_master structures, and allocate the
    master structures in the body of jpeg_create_compress() and
    jpeg_create_decompress().

  * Remove the new 'process' field from jpeg_compress_struct and
    jpeg_decompress_struct and replace it with the old
    'progressive_mode' field and the new 'lossless' field.

  * Remove the new 'data_unit' field from jpeg_compress_struct and
    jpeg_decompress_struct and replace it with a locally-computed
    data unit variable.

  * Restore the names of macros and fields that refer to DCT blocks, and
    document that they have a different meaning in lossless mode.  (Most
    of them aren't very meaningful in lossless mode anyhow.)

  * Remove the new alloc_darray() method from jpeg_memory_mgr and
    replace it with an internal macro that wraps the alloc_sarray()
    method.

  * Move the JDIFF* data types from jpeglib.h and jmorecfg.h into
    jpegint.h.

  * Remove the new 'codec' field from jpeg_compress_struct and
    jpeg_decompress_struct and instead reuse the existing internal
    coefficient control, forward/inverse DCT, and entropy
    encoding/decoding structures for lossless compression/decompression.

  * Repurpose existing error codes rather than introducing new ones.
    (The new JERR_BAD_RESTART and JWRN_MUST_DOWNSCALE codes remain,
    although JWRN_MUST_DOWNSCALE will probably be removed in
    libjpeg-turbo, since we have a different way of handling multiple
    data precisions.)

- Automatically enable lossless mode when a scan script with parameters
  that are only valid for lossless mode is detected, and document the
  use of scan scripts to generate lossless JPEG images.

- Move the sequential and shared Huffman routines back into jchuff.c and
  jdhuff.c, and document that those routines are shared with jclhuff.c
  and jdlhuff.c as well as with jcphuff.c and jdphuff.c.

- Move MAX_DIFF_BITS from jchuff.h into jclhuff.c, the only place where
  it is used.

- Move the predictor and scaler code into jclossls.c and jdlossls.c.

- Streamline register usage in the [un]differencers (inspired by similar
  optimizations in the color [de]converters.)

- Restructure the logic in a few places to reduce duplicated code.

- Ensure that all lossless-specific code is guarded by
  C_LOSSLESS_SUPPORTED or D_LOSSLESS_SUPPORTED and that the library can
  be built successfully if either or both of those macros is undefined.

- Remove all short forms of external names introduced by the lossless
  JPEG patch.  (These will not be needed by libjpeg-turbo, so there is
  no use cleaning them up.)

- Various wordsmithing, formatting, and punctuation tweaks

- Eliminate various compiler warnings.
2022-11-14 14:55:04 -06:00
DRC
b5a9ef64ea Don't allow 12-bit JPEG support to be disabled
In libjpeg-turbo 2.1.x and prior, the WITH_12BIT CMake variable was used
to enable 12-bit JPEG support at compile time, because the libjpeg API
library could not handle multiple JPEG data precisions at run time.  The
initial approach to handling multiple JPEG data precisions at run time
(7fec5074f9) created a whole new API,
library, and applications for 12-bit data precision, so it made sense to
repurpose WITH_12BIT to allow 12-bit data precision to be disabled.
e8b40f3c2b made it so that the libjpeg API
library can handle multiple JPEG data precisions at run time via a
handful of straightforward API extensions.  Referring to
6c2bc901e2, it hasn't been possible to
build libjpeg-turbo with both forward and backward libjpeg API/ABI
compatibility since libjpeg-turbo 1.4.x.  Thus, whereas we retain full
backward API/ABI compatibility with libjpeg v6b-v8, forward libjpeg
API/ABI compatibility ceased being realistic years ago, so it no longer
makes sense to provide compile-time options that give a false sense of
forward API/ABI compatibility by allowing some (but not all) of our
libjpeg API extensions to be disabled.  Such options are difficult to
maintain and clutter the code with #ifdefs.
2022-11-13 13:38:48 -06:00
DRC
9ca7919a40 OSS-Fuzz: Fix bug in the new cjpeg12 fuzzer
cjpeg doesn't accept image format arguments other than -targa (it
auto-detects the others), and since Targa images aren't supported with
12-bit precision, we don't need a second pass.
2022-11-07 10:39:03 -06:00
DRC
bf01ed2fbc Fix build when SIMD extensions are disabled
(Broken by previous commit)
2022-11-04 13:35:03 -05:00
DRC
e8b40f3c2b Vastly improve 12-bit JPEG integration
The Gordian knot that 7fec5074f9 attempted
to unravel was caused by the fact that there are several
data-precision-dependent (JSAMPLE-dependent) fields and methods in the
exposed libjpeg API structures, and if you change the exposed libjpeg
API structures, then you have to change the whole API.  If you change
the whole API, then you have to provide a whole new library to support
the new API, and that makes it difficult to support multiple data
precisions in the same application.  (It is not impossible, as example.c
demonstrated, but using data-precision-dependent libjpeg API structures
would have made the cjpeg, djpeg, and jpegtran source code hard to read,
so it made more sense to build, install, and package 12-bit-specific
versions of those applications.)

Unfortunately, the result of that initial integration effort was an
unreadable and unmaintainable mess, which is a problem for a library
that is an ISO/ITU-T reference implementation.  Also, as I dug into the
problem of lossless JPEG support, I realized that 16-bit lossless JPEG
images are a thing, and supporting yet another version of the libjpeg
API just for those images is untenable.

In fact, however, the touch points for JSAMPLE in the exposed libjpeg
API structures are minimal:

  - The colormap and sample_range_limit fields in jpeg_decompress_struct
  - The alloc_sarray() and access_virt_sarray() methods in
    jpeg_memory_mgr
  - jpeg_write_scanlines() and jpeg_write_raw_data()
  - jpeg_read_scanlines() and jpeg_read_raw_data()
  - jpeg_skip_scanlines() and jpeg_crop_scanline()
    (This is subtle, but both of those functions use JSAMPLE-dependent
    opaque structures behind the scenes.)

It is much more readable and maintainable to provide 12-bit-specific
versions of those six top-level API functions and to document that the
aforementioned methods and fields must be type-cast when using 12-bit
samples.  Since that eliminates the need to provide a 12-bit-specific
version of the exposed libjpeg API structures, we can:

  - Compile only the precision-dependent libjpeg modules (the
    coefficient buffer controllers, the colorspace converters, the
    DCT/IDCT managers, the main buffer controllers, the preprocessing
    and postprocessing controller, the downsampler and upsamplers, the
    quantizers, the integer DCT methods, and the IDCT methods) for
    multiple data precisions.
  - Introduce 12-bit-specific methods into the various internal
    structures defined in jpegint.h.
  - Create precision-independent data type, macro, method, field, and
    function names that are prefixed by an underscore, and use an
    internal header to convert those into precision-dependent data
    type, macro, method, field, and function names, based on the value
    of BITS_IN_JSAMPLE, when compiling the precision-dependent libjpeg
    modules.
  - Expose precision-dependent jinit*() functions for each of the
    precision-dependent libjpeg modules.
  - Abstract the precision-dependent libjpeg modules by calling the
    appropriate precision-dependent jinit*() function, based on the
    value of cinfo->data_precision, from top-level libjpeg API
    functions.
2022-11-04 12:30:33 -05:00
DRC
6c2bc901e2 Don't allow disabling in-memory src/dest managers
By default, libjpeg-turbo 1.3.x and later have enabled the in-memory
source/destination manager functions from libjpeg v8 when emulating the
libjpeg v6b or v7 API/ABI, which has allowed operating system
distributors to provide those functions without adopting the
backward-incompatible libjpeg v8 API/ABI.

Prior to libjpeg-turbo 1.5.x, it made sense to allow users to disable
the in-memory source/destination manager functions at build time and
thus retain both backward and forward API/ABI compatibility relative to
libjpeg v6b or v7.  Since then, however, we have introduced several new
libjpeg API functions that break forward API/ABI compatibility, so it no
longer makes sense to allow the in-memory source/destination managers to
be disabled.  libjpeg-turbo only claims to be
backward-API/ABI-compatible, i.e. to allow applications built against
libjpeg or an older version of libjpeg-turbo to work properly with the
current version of libjpeg-turbo.
2022-11-03 15:22:19 -05:00
DRC
664b64a9ac Merge branch 'main' into dev 2022-11-03 14:25:35 -05:00
DRC
4f7a8afbb7 Build: Fix issues w/ Ninja Multi-Config generator
- Fix an issue whereby a build with ENABLE_SHARED=0 could not be
  installed when using the Ninja Multi-Config CMake generator.

- Fix an issue whereby a Windows installer could not be built when using
  the Ninja Multi-Config CMake generator.

- Fix an issue whereby the Java regression tests failed when using the
  Ninja Multi-Config CMake generator.

Based on:
4f169deeb0

Closes #626
2022-11-03 14:23:55 -05:00
DRC
8c5e78ce29 Build: Document SO_AGE and TURBOJPEG_SO_AGE vars 2022-11-03 14:23:03 -05:00
DRC
8917c54877 ChangeLog.md: Add colons to sub-headers
For some reason, I failed to add a colon to the "Significant changes
relative to 2.1 beta1" sub-header, and the mistake propagated from
there.
2022-11-03 14:20:22 -05:00
DRC
cb3642cb0b Bump version to 2.1.5 to prepare for new commits 2022-11-03 12:23:11 -05:00
DRC
ec6e451d05 Lossless JPEG support: Add copyright attributions
Referring to
https://github.com/libjpeg-turbo/libjpeg-turbo/issues/402#issuecomment-768348440
and
https://github.com/libjpeg-turbo/libjpeg-turbo/issues/402#issuecomment-770221584

Ken Murchison clarified that it was his intent to release the lossless
JPEG patch under the IJG License and that adding his name to the
copyright headers would be sufficient to acknowledge that any
derivatives are based on his work.
2022-10-21 16:53:53 -05:00
DRC
2df43f51f1 Lossless JPEG support: Fix build
(Modern compilers require function prototypes.)
2022-10-21 16:32:34 -05:00
Ken Murchison
2e8360e061 IJG's JPEG software v6b with lossless JPEG support
Patch obtained from:
https://sourceforge.net/projects/jpeg/files/ftp.oceana.com

Author date taken from original announcement and timestamp of patch
tarball:
https://groups.google.com/g/comp.protocols.dicom/c/rrkP8BxoMRk/m/Ij4dfprggp8J
2022-10-21 13:42:59 -05:00
DRC
4d269d7cd5 Merge branch 'main' into dev 2022-10-21 12:22:28 -05:00
DRC
51f1924e77 wizard.txt: Clarify scan script restrictions
The Wallace paper is not entirely clear on these restrictions, and the
spec itself requires some digging.

Closes #624
2022-10-21 12:20:41 -05:00
DRC
5acd9f2061 Merge branch 'main' into dev 2022-10-04 12:58:11 -05:00
DRC
eb0a024af2 Remove redundant jconfigint.h #includes
Because of 607b668ff9, jconfigint.h is
included by jinclude.h.
2022-10-04 12:51:52 -05:00
DRC
543bfc25f5 Merge branch 'main' into dev 2022-10-03 21:38:15 -05:00
DRC
f579cc11b3 Make SIMD capability variables thread-local ...
... on platforms that support TLS, which should include all
currently-supported platforms
(https://libjpeg-turbo.org/Documentation/OfficialBinaries)

Addresses a concern raised in #87

Although it is still my opinion that the data race in init_simd() was
innocuous, we can now fix it for free thanks to
ae87a95861, so why not?
2022-10-03 21:36:21 -05:00
DRC
2fd634b833 Merge branch 'main' into dev 2022-09-12 23:36:34 -05:00
DRC
2cad2169ae BUILDING.md: Acknowledge RHEL 9 2022-09-12 21:54:35 -05:00
DRC
b3d3cbf43d JNI: Remove deprecated methods
(oversight from 931884e78d)
2022-09-12 14:41:34 -05:00
DRC
fdfba4957c Merge branch 'main' into dev 2022-09-02 15:11:25 -05:00
DRC
c5db99e1aa GitHub Actions: Specify Big Sur for macOS build
The Catalina hosted runner is now fully deprecated.
2022-09-02 14:48:58 -05:00
Kornel
fd56921259 Merge commit '8162eddf041e0be26f5c671bb6528723c55fed9d'
* commit '8162eddf041e0be26f5c671bb6528723c55fed9d': (24 commits)
  Fix issues w/ partial img decompr + buf img mode
  Re-fix buf img mode decompr err w/short prog JPEGs
  jdcoefct.c: Fix signed/unsigned mismatch VC++ wrng
  Fix buf image mode decompr err w/ short prog JPEGs
  PowerPC: Detect AltiVec support on OS X
  tjDecompressHeader3(): Accept tables-only streams
  Fix build if UPSAMPLE_MERGING_SUPPORTED undefined
  Build: Don't enable Loongson MMI with MIPS R6+
  MinGW: Fix str*casecmp() macro redef. warning
  OSS-Fuzz: '.' --> '_' in fuzzer suffix
  Don't install libturbojpeg.pc if WITH_TURBOJPEG=0
  Fix non-SIMD alignment if void* bigger than double
  OSS-Fuzz: Allow fuzzer suffix to be specified
  CI: Un-integrate CIFuzz
  BUILDING.md: Generify PowerTools repo advice
  Build: Don't set DEFAULT_FLOATTEST for x86 MSVC
  Build/Win: Fix CMake warning when WITH_TURBOJPEG=0
  Win: Fix build with Visual Studio 2010
  Link Sponsor button to GitHub Sponsors ...
  example.txt: Fix a typo
  ...
2022-08-15 02:46:09 +01:00
Kornel
a2d2907ff0 Fix env var name typo 2022-08-15 02:13:17 +01:00
DRC
513f9e6628 Merge branch 'main' into dev 2022-08-09 04:27:33 -05:00
DRC
8162eddf04 Fix issues w/ partial img decompr + buf img mode
Fixes #611
2022-08-08 16:03:55 -05:00
DRC
931884e78d Java: Remove deprecated fields, ctors, and methods
Most of these have been deprecated since libjpeg-turbo 1.4.x.
It's time.
2022-08-08 15:41:01 -05:00
DRC
280784f7ab Merge branch 'main' into dev 2022-08-08 15:07:45 -05:00
DRC
2e136a7190 Re-fix buf img mode decompr err w/short prog JPEGs
This commit reverts 4dbc293125 and
9f8f683e74 (the previous two commits) and
fixes #613 the correct way.  The crux of the issue wasn't the size of
the whole_image virtual array but rather that, since last_iMCU_row is
unsigned, (last_iMCU_row - 1) wrapped around to 0xFFFFFFFF when
last_iMCU_row was 0.  This caused the interblock smoothing algorithm
introduced in 6d91e950c8 to erroneously
try to access the next two iMCU rows, neither of which existed.  The
first attempt at a fix (4dbc293125)
exposed a NULL dereference, detected by OSS-Fuzz, that occurred when
attempting to decompress a specially-crafted malformed JPEG image to a
YUV buffer using tjDecompressToYUV*() with 1/4 IDCT scaling.

Fixes #613 (again)
Also fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=49898
2022-08-08 15:06:56 -05:00
DRC
f627319258 Merge branch 'main' into dev 2022-08-07 14:16:28 -05:00
DRC
9f8f683e74 jdcoefct.c: Fix signed/unsigned mismatch VC++ wrng
(introduced by previous commit)
2022-08-07 14:15:03 -05:00
DRC
9a60181b3d Merge branch 'main' into dev 2022-08-07 13:48:31 -05:00
DRC
4dbc293125 Fix buf image mode decompr err w/ short prog JPEGs
Regression introduced by 6d91e950c8

Because we're now using a 5x5 smoothing window when decompressing
progressive JPEG images, we need to ensure that the whole_image virtual
array contains at least five rows.  Previously that was not always the
case unless the progressive JPEG image being decompressed had at least
five iMCU rows.  Since an iMCU has a height of (8 * the vertical
sampling factor), attempting to decompress 4:2:2 and 4:4:4 images <= 32
pixels in height or 4:2:0 images <= 64 pixels in height triggered a
JERR_BAD_VIRTUAL_ACCESS error in decompress_smooth_data(), because
access_rows exceeded the number of rows in the virtual array.

Fixes #613
2022-08-07 13:38:47 -05:00
DRC
fc224c4889 Merge branch 'main' into dev 2022-07-07 13:11:05 -05:00
Donovan Watteau
59337a67b1 PowerPC: Detect AltiVec support on OS X
libjpeg-turbo's AltiVec SIMD extensions previously assumed that AltiVec
instructions were available on all Power Macs that supported OS X 10.4
"Tiger" (the earliest version of OS X that libjpeg-turbo has ever
supported), but Tiger can actually run on PowerPC G3 processors, which
lack AltiVec instructions.  This commit enables run-time detection of
AltiVec instructions on OS X/PowerPC systems if AltiVec instructions are
not force-enabled at compile time (using -maltivec).  This allows the
same build of libjpeg-turbo to support G3, G4, and G5 Power Macs.

Closes #609
2022-07-07 13:01:11 -05:00
DRC
8a3b0f70d2 Implement 12-bit-specific error/warn/trace macros
The macros in jerror.h refer to j_common_ptr, so it is unfortunately
necessary to introduce a 12-bit-specific version of that header file
(j12error.h) with 12-bit specific ERREXIT*(), WARNMS*(), and
TRACEMS*() macros.  (The message table is still shared between 8-bit and
12-bit implementations.)

Fixes #607
2022-06-24 15:36:28 -05:00
Jon Craton
08978e58db Update quant-table help
Update cjpeg -help for quant-table entry to include 3 additional tables listed in README-mozilla.txt and indicate the default table.
2022-06-24 21:20:21 +01:00
DRC
aa5a359945 Merge branch 'main' into dev 2022-06-24 14:21:33 -05:00
DRC
ba22c0f76d tjDecompressHeader3(): Accept tables-only streams
Inspired by:
b3b15cfe74

Closes #604
Closes #605
2022-06-24 14:10:44 -05:00
DRC
225781aff9 jchuff.c: Clean up aadd60ae + add code comments
Based on:
4d73f52032
184f10703e

Refer to #602
2022-06-14 15:15:34 -05:00
DRC
faa7c74aef ChangeLog.md: Acknowledge 2.1.4 release 2022-05-31 13:37:05 -05:00
Felix Hanau
aadd60ae49 Speed up computation of optimal Huffman tables
Closes #602
2022-05-31 13:37:00 -05:00
DRC
0000dadf17 Merge branch 'main' into dev 2022-05-27 12:15:04 -05:00
DRC
a405519e96 Fix build if UPSAMPLE_MERGING_SUPPORTED undefined
Although it is uncommon, some downstream implementations undefine one or
more of the *_SUPPORTED macros in jmorecfg.h in order to reduce the size
of the library.  In the interest of maintaining backward compatibility
with libjpeg, this is still a supported use case.

Regression introduced by 9120a24743

Based on:
74c4d032f0

Closes #601
2022-05-27 11:59:56 -05:00
Jiaxun Yang
fac8381441 Build: Don't enable Loongson MMI with MIPS R6+
MIPS R6 removed some instructions, so Loongson MMI cannot be built with
MIPS R6+ toolchains.

Closes #598
2022-05-24 09:25:55 -05:00
Kornel
5c6a0f0971 Update to libjpeg-turbo 2.1.3 2022-05-23 16:06:07 +01:00
Kornel
5e797fa699 Merge tag '2.1.3' into master-moz
* tag '2.1.3': (56 commits)
  Neon/AArch64: Explicitly unroll quant loop w/Clang
  Neon/AArch64: Fix/suppress UBSan warnings
  Neon/AArch64: Accelerate Huffman encoding
  AppVeyor: Test strict MSVC compiler warnings
  Eliminate incompatible pointer type warnings
  MSVC: Eliminate int conversion warnings (C4244)
  MSVC: Eliminate C4996 warnings in API libs
  BUILDING.md: Clarify that Ninja works with Windows
  BUILDING.md: Remove NASM RPM rebuild instructions
  BUILDING.md: Document NASM/Yasm path variables
  "YASM" = "Yasm"
  Build: Fix Neon capability detection w/ MSVC
  Ensure that strncpy() dest strings are terminated
  Eliminate unnecessary JFREAD()/JFWRITE() macros
  Build: Embed version/API/(C) info in MSVC DLLs
  Fix segv w/ h2v2 merged upsamp, jpeg_crop_scanline
  TJBench: Remove innocuous always-true condition
  GitHub Actions: Specify Catalina for macOS build
  Fix -Wpedantic compiler warnings
  Eliminate non-ANSI C compatibility macros
  ...
2022-05-23 16:04:06 +01:00
DRC
0f5d31e62f Merge branch 'main' into dev 2022-04-28 20:04:53 -05:00
modbw
290ddbf71a MinGW: Fix str*casecmp() macro redef. warning
MinGW defines strcasecmp() and strncasecmp() as macros in string.h if
__CRT__NO_INLINE is defined, which will be the case when including any
of the Win32 API headers.

Closes #594
2022-04-28 20:02:28 -05:00
DRC
b98dabac24 Merge branch 'main' into dev 2022-04-27 12:38:58 -05:00
DRC
9171fd4bde OSS-Fuzz: '.' --> '_' in fuzzer suffix
Referring to https://github.com/google/oss-fuzz/issues/7575, if the
fuzzer suffix contains periods, it can cause ClusterFuzz to misinterpret
the file extension of the fuzzer executables and thus misidentify them.
2022-04-27 12:34:28 -05:00
DRC
d0e7c4548a Don't install libturbojpeg.pc if WITH_TURBOJPEG=0
Fixes #593
2022-04-18 11:34:57 -05:00
Alex Richardson
dfc63d42ee Fix non-SIMD alignment if void* bigger than double
When building without the SIMD extensions, memory allocations are
currently aligned to sizeof(double).  However, this may be insufficient
on architectures such as Arm Morello or 64-bit CHERI-RISC-V where
pointers require 16-byte rather than 8-byte alignment.  This patch
causes memory allocations to be aligned to
MAX(sizeof(void *), sizeof(double)) when building without the SIMD
extensions.

(NOTE: With C11 we could instead use alignof(max_align_t), but C89
compatibility is still necessary in libjpeg-turbo.)

Closes #587
2022-04-12 13:53:56 -05:00
DRC
82081337a0 Merge branch 'main' into dev 2022-04-06 11:16:09 -05:00
DRC
67cb059046 OSS-Fuzz: Allow fuzzer suffix to be specified
This facilitates fuzzing multiple branches of the code.
2022-04-06 11:15:54 -05:00
DRC
5c8cac97c0 CI: Un-integrate CIFuzz
Referring to the conversation in
https://github.com/google/oss-fuzz/issues/7479 and #559, there was a
misunderstanding regarding how CIFuzz works.  It cannot be used to fuzz
arbitrary PRs or code branches, and it has a 90-day delay in downloading
corpora from OSS-Fuzz.  That makes it unsuitable for libjpeg-turbo.
2022-04-06 10:58:53 -05:00
DRC
89a369dec1 Merge branch 'main' into dev 2022-03-31 10:33:26 -05:00
DRC
df3c3dcb9b BUILDING.md: Generify PowerTools repo advice
This advice applies to CentOS Stream as well as to popular CentOS 8
replacements, such as Rocky Linux and AlmaLinux.
2022-03-31 10:28:17 -05:00
DRC
1b9edb5caf Build: Fix 12-bit FP tests w/ 32-bit builds
With x86-64 builds, the default value of FLOATTEST works with both the
8-bit-per-sample and 12-bit-per-sample flavors of the libjpeg API
library.  However, that is not the case with x86 builds.  Thus, we need
separate 8-bit-per-sample and 12-bit-per-sample FLOATTEST variables.
2022-03-11 17:41:18 -06:00
DRC
cb715fe1ae example.c: Fix compiler warning with GCC 4.4.7 2022-03-11 17:36:05 -06:00
DRC
ebd1930207 GitHub Actions: "linux-12bit" --> "linux-no12bit"
This job tests the non-default value of WITH_12BIT, which is now 0
instead of 1.
2022-03-11 17:36:05 -06:00
DRC
263386c23a Merge branch 'main' into dev 2022-03-11 17:35:59 -06:00
DRC
2ee7264d40 Build: Don't set DEFAULT_FLOATTEST for x86 MSVC
Newer versions of the 32-bit x86 Visual Studio compiler produce results
compatible with FLOATTEST=no-fp-contract, so we can no longer
intelligently set a default FLOATTEST value for that platform.
2022-03-11 17:32:58 -06:00
DRC
30cba2a2f8 Build/Win: Fix CMake warning when WITH_TURBOJPEG=0
When 12-bit-per-component JPEG support is enabled (WITH_12BIT=1) or the
TurboJPEG API library and associated test programs are disabled
(WITH_TURBOJPEG=0), the Windows installer target should not depend on
the turbojpeg, turbojpeg-static, and tjbench targets.
2022-03-11 11:55:50 -06:00
DRC
a014845403 Win: Fix build with Visual Studio 2010
(broken by 607b668ff9)

- Visual Studio 2010 apparently doesn't have the snprintf() inline
  function, so restore the macro that emulates that function using
  _snprintf_s().

- Explicitly include errno.h in strtest.c, since jinclude.h doesn't
  include it when building with Visual Studio.
2022-03-11 11:19:40 -06:00
DRC
b3ae777964 Fix in-tree builds
(oops)
2022-03-10 23:13:43 -06:00
DRC
a32038e3b3 Fix formatting issues detected by checkstyle 2022-03-10 23:10:12 -06:00
DRC
7fec5074f9 Support 8-bit & 12-bit JPEGs using the same build
Partially implements #199

This commit also implements a request from #178 (the ability to compile
the libjpeg example as a standalone program.)
2022-03-10 22:56:17 -06:00
DRC
fc562d11f0 Bump version to 2.2 alpha1 ...
... to prepare for new features
2022-03-10 22:56:17 -06:00
DRC
f3c716a2bc Link Sponsor button to GitHub Sponsors ...
... instead of PayPal.
2022-03-10 22:31:20 -06:00
DRC
6f1534d618 example.txt: Fix a typo 2022-03-09 12:58:55 -06:00
DRC
9abeff46d8 Remove extraneous #include directives
jinclude.h already includes stdio.h, stdlib.h, and string.h.
2022-03-09 11:49:27 -06:00
DRC
932b5bb0d5 IJG dox: Wordsmithing and formatting tweaks
- Remove the section in libjpeg.txt that advised against building
  libjpeg as a shared library.  We obviously do not follow that advice,
  and libjpeg-turbo does guarantee backward ABI compatibility in our
  libjpeg API library, even though libjpeg did not and does not.
  (Future expansion of our libjpeg API library, if necessary, will be
  accomplished using get/set functions that store the new parameters
  in the opaque master structs.  Refer to
  db2986c96f.)

- Unmention install.txt, which was never relevant to libjpeg-turbo and
  was removed in v1.3 (6f96153c67).

- Remove extraneous spaces.

- Document the fact that TWO_FILE_COMMANDLINE must be defined in order
  to use the two-file interface with cjpeg, djpeg, jpegtran, and
  wrjpgcom.  libjpeg-turbo never enables that interface by default.
2022-03-09 11:49:27 -06:00
Adam Fontenot
e8df8a2d63 Fix broken test jpegtran-*-420-islow-ari 2022-03-09 12:03:31 +00:00
DRC
fdab4a7af4 Progs: Eliminate obsolete Mac ccommand() interface
ccommand() was a 1990s-vintage hack for running console applications
without a console.  It doesn't exist in any modern macOS compiler.
2022-03-08 17:31:11 -06:00
DRC
0565548191 BUILDING.md: Mention sub-project best practices
People keep trying to include libjpeg-turbo into downstream CMake-based
build systems by way of the add_subdirectory() function and requesting
upstream support when something inevitably breaks.

(Refer to: #122, #173, #176, #202, #241, #349, #353, #412, #504,
a3d4aadd0d (commitcomment-67575889)).

libjpeg-turbo has never supported that method of sub-project
integration, because doing so would require that we (minimally):

1. avoid using certain CMake variables, such as CMAKE_SOURCE_DIR,
   CMAKE_BINARY_DIR, and CMAKE_PROJECT_NAME;
2. avoid using implicit include directories and relative paths;
3. provide a way to optionally skip the installation of libjpeg-turbo
   components in response to 'make install';
4. provide a way to optionally postfix target names, to avoid namespace
   conflicts;
5. restructure the top-level CMakeLists.txt so that it properly sets
   the PROJECT_VERSION variable; and
6. design automated CI tests to ensure that new commits don't break
   any of the above.

Even if we did all of that, issues would still arise, because it is
impossible for one upstream build system to anticipate the widely
varying needs of every downstream build system.  That's why the CMake
ExternalProject_Add() function exists, and it is my sincere hope that
adding a blurb to BUILDING.md mentioning the need to use that function
will head off future GitHub issues on this topic.  If not, then I can at
least post a link to this commit and the blurb and avoid doing the same
song and dance over and over again.
2022-02-28 22:27:58 -06:00
Jonathan Wright
c5f269eb96 Neon/AArch64: Explicitly unroll quant loop w/Clang
The loop in jsimd_quantize_neon() is only executed twice and should be
unrolled for AArch64 targets.  GCC does that by default, but Clang 11
and later versions available at the time of this writing do not.  This
patch adds an unroll pragma when targetting AArch64 with Clang.  We do
not use the unroll pragma for AArch32 targets, because it causes the
Clang-generated assembly code to exhaust the available Neon registers
(32 x 64-bit) and spill to the stack.  (DRC: Referring to the discussion
in #570, this is likely due to compiler confusion that results in poor
register allocation.  It is possible to eliminate the spillage and
reduce the instruction count by loading the data on a just-in-time
basis, thus explicitly interleaving compute and I/O, but the performance
implications of that are currently unknown.)

The effects of unrolling the quantization loop are:
1) elimination of the loop control flow overhead and
2) enabling the use of LDP/STP instructions that work from a single
   base pointer, instead of using double the number of LDR/STR
   instructions, each requiring an address calculation.

Closes #570
2022-02-25 12:53:05 -06:00
DRC
98bc3eeb3a Neon/AArch64: Fix/suppress UBSan warnings
- Suppress a UBSan warning regarding storing a 64-bit value to a
  non-64-bit-aligned address.  That behavior is technically undefined
  per the C spec but is supported in the context of the AArch64
  architecture and compilers.

- Explicitly promote block_diff[i] to unsigned int prior to left
  shifting it, in order to avoid a UBSan warning.  This warning also
  described behavior that is technically undefined per the C spec but is
  supported in the context of the AArch64 architecture and compilers.
  Changing the type cast order eliminated the warning without changing
  the generated assembly code.

Closes #582
2022-02-25 00:02:14 -06:00
Jonathan Wright
147548c055 Neon/AArch64: Accelerate Huffman encoding
- Make better use of 128-bit vector registers, thus reducing the number
  of Neon instructions required to construct the AC coefficient bitmap.

- Refactor the Neon computations of 'nbits' and 'diff' to use shorter
  and higher-throughput instruction sequences.

DRC's notes:

This commit partially integrates #570.  Arm reported a 1-4% speedup on
Cortex-A55 and Neoverse-N1 cores when using recent compilers but little
or no speedup with Clang 10.  I observed no speedup with Clang 10 on my
Cortex-A53 and Cortex-A72 cores.  Thus, referring to #582, the primary
purpose of this commit is to fix UBSan warnings regarding the shift
operations previously located at Line 253:

d640a45730/simd/arm/aarch64/jchuff-neon.c (L253)
2022-02-24 23:31:32 -06:00
DRC
d640a45730 AppVeyor: Test strict MSVC compiler warnings 2022-02-23 17:02:24 -06:00
DRC
eb21c023ab Eliminate incompatible pointer type warnings
(C4057 in MSVC and -Wincompatible-pointer-types in GCC/Clang)
2022-02-23 15:57:05 -06:00
DRC
13377e6b38 MSVC: Eliminate int conversion warnings (C4244) 2022-02-23 15:57:05 -06:00
DRC
607b668ff9 MSVC: Eliminate C4996 warnings in API libs
The primary purpose of this is to encourage adoption of libjpeg-turbo in
downstream Windows projects that forbid the use of "deprecated"
functions.  libjpeg-turbo's usage of those functions was not actually
unsafe, because:

- libjpeg-turbo always checks the return value of fopen() and ensures
  that a NULL filename can never be passed to it.

- libjpeg-turbo always checks the return value of getenv() and never
  passes a NULL argument to it.

- The sprintf() calls in format_message() (jerror.c) could never
  overflow the destination string buffer or leave it unterminated as
  long as the buffer was at least JMSG_LENGTH_MAX bytes in length, as
  instructed. (Regardless, this commit replaces those calls with
  snprintf() calls.)

- libjpeg-turbo never uses sscanf() to read strings or multi-byte
  character arrays.

- Because of b7d6e84d6a, wrjpgcom
  explicitly checks the bounds of the source and destination strings
  before calling strcat() and strcpy().

- libjpeg-turbo always ensures that the destination string is
  terminated when using strncpy().
  (548490fe5e made this explicit.)

Regarding thread safety:

Technically speaking, getenv() is not thread-safe, because the returned
pointer may be invalidated if another thread sets the same environment
variable between the time that the first thread calls getenv() and the
time that that thread uses the return value.  In practice, however, this
could only occur with libjpeg-turbo if:

(1) A multithreaded calling application used the deprecated and
undocumented TJFLAG_FORCEMMX/TJFLAG_FORCESSE/TJFLAG_FORCESSE2 flags in
the TurboJPEG API or set one of the corresponding environment variables
(which are only intended for testing purposes.)  Since the TurboJPEG API
library only ever passed string constants to putenv(), the only inherent
risk (i.e. the only risk introduced by the library and not the calling
application) was that the SIMD extensions may have read an incorrect
value from one of the aforementioned environment variables.

or

(2) A multithreaded calling application modified the value of the
JPEGMEM environment variable in one thread while another thread was
reading the value of that environment variable (in the body of
jpeg_create_compress() or jpeg_create_decompress().)  Given that the
libjpeg API provides a thread-safe way for applications to modify the
default memory limit without using the JPEGMEM environment variable,
direct modification of that environment variable by calling applications
is not supported.

Microsoft's implementation of getenv_s() does not claim to be
thread-safe either, so this commit uses getenv_s() solely to mollify
Visual Studio.  New inline functions and macros (GETENV_S() and
PUTENV_S) wrap getenv_s()/_putenv_s() when building for Visual Studio
and getenv()/setenv() otherwise, but GETENV_S()/PUTENV_S() provide no
advantages over getenv()/setenv() other than parameter validation.  They
are implemented solely for convenience.

Technically speaking, strerror() is not thread-safe, because the
returned pointer may be invalidated if another thread changes the locale
and/or calls strerror() between the time that the first thread calls
strerror() and the time that that thread uses the return value.  In
practice, however, this could only occur with libjpeg-turbo if a
multithreaded calling application encountered a file I/O error in
tjLoadImage() or tjSaveImage().  Since both of those functions
immediately copy the string returned from strerror() into a thread-local
buffer, the risk is minimal, and the worst case would involve an
incorrect error string being reported to the calling application.
Regardless, this commit uses strerror_s() in the TurboJPEG API library
when building for Visual Studio.  Note that strerror_r() could have been
used on Un*x systems, but it would have been necessary to handle both
the POSIX and GNU implementations of that function and perform
widespread compatibility testing.  Such is left as an exercise for
another day.

Fixes #568
2022-02-23 15:57:01 -06:00
DRC
ab6cae6f3b BUILDING.md: Clarify that Ninja works with Windows 2022-02-22 10:23:19 -06:00
DRC
3ccb6ead23 BUILDING.md: Remove NASM RPM rebuild instructions
All currently supported Linux platforms now provide a recent enough
version of either NASM or Yasm.
2022-02-11 10:05:18 -06:00
DRC
6441ad0f83 BUILDING.md: Document NASM/Yasm path variables
This was an oversight from the CMake build system overhaul in
libjpeg-turbo 2.0 (6abd39160c).

Closes #580
2022-02-11 10:02:28 -06:00
DRC
6d2d6d3baf "YASM" = "Yasm"
The assembler name was initially spelled "YASM", but it has been "Yasm"
for the entirety of libjpeg-turbo's existence.
2022-02-11 09:34:01 -06:00
DRC
e1588a2a7b Build: Fix Neon capability detection w/ MSVC
(broken by 57ba02a408)

Refer to #547
2022-02-10 22:24:19 -06:00
DRC
548490fe5e Ensure that strncpy() dest strings are terminated
- Since the ERREXITS() and TRACEMSS() macros are never used internally
  (they are a relic of the legacy memory managers that libjpeg
  provided), the only risk was that an external program might have
  invoked one of those macros with a string longer than 79 characters
  (JMSG_STR_PARM_MAX - 1).

- TJBench never invokes the THROW_TJ() macro with a string longer than
  199 (JMSG_LENGTH_MAX - 1) characters, so there was no risk.  However,
  it's a good idea to explicitly terminate the destination strings so
  that anyone looking at the code can immediately tell that it is safe.
2022-02-10 11:52:48 -06:00
DRC
b579fc114d Eliminate unnecessary JFREAD()/JFWRITE() macros 2022-02-09 16:07:18 -06:00
DRC
a3d4aadd0d Build: Embed version/API/(C) info in MSVC DLLs
Based on:
da7a18801a

Closes #576
2022-02-01 13:00:42 -06:00
DRC
d7d16df646 Fix segv w/ h2v2 merged upsamp, jpeg_crop_scanline
The h2v2 (4:2:0) merged upsampler uses a spare row buffer so that it can
upsample two rows at a time but return only one row to the application,
if necessary.  merged_2v_upsample() copies from this spare row buffer
into the application-supplied output buffer, using the out_row_width
field in the my_merged_upsampler struct to determine how many samples to
copy.  out_row_width is set in jinit_merged_upsampler(), which is called
within the body of jpeg_start_decompress().  Since jpeg_crop_scanline()
must be called after jpeg_start_decompress(), jpeg_crop_scanline() must
modify the value of out_row_width if the h2v2 merged upsampler will be
used.  Otherwise, merged_2v_upsample() can overflow the output buffer if
the number of bytes between the current output buffer position and the
end of the buffer is less than the number of bytes required to represent
an uncropped scanline of the output image.  All of the destination
managers used by djpeg allocate either a whole image buffer or a
scanline buffer based on the uncropped output image width, so this issue
is not reproducible using djpeg.

Fixes #574
2022-02-01 10:52:08 -06:00
DRC
14ce28a92d TJBench: Remove innocuous always-true condition
This was accidentally introduced into tjbench.c in
890f1e0413 and ported into the Java
version from there.

Based on
4be6d4e7bd

Refer to #571
2022-01-29 12:37:15 -06:00
DRC
da41ab94e7 GitHub Actions: Specify Catalina for macOS build
macos-latest now maps to the Big Sur image, which doesn't have Xcode
12.2 installed.
2022-01-06 12:57:26 -06:00
DRC
1f55ae7b0f Fix -Wpedantic compiler warnings
... and test for those warnings (and others) when performing CI builds.
2022-01-06 12:33:22 -06:00
DRC
172972394a Eliminate non-ANSI C compatibility macros
libjpeg-turbo has never supported non-ANSI C compilers.  Per the spec,
ANSI C compilers must have locale.h, stddef.h, stdlib.h, memset(),
memcpy(), unsigned char, and unsigned short.  They must also handle
undefined structures.
2022-01-06 11:50:26 -06:00
Dmitry Tsarevich
a7f0244e9b turbojpeg.h: Parenthesize TJSCALED() dimension arg
This ensures that, for example,
TJSCALED(dim0 + dim1, sf)

will evaluate to
(((dim0 + dim1) * sf.num + sf.denom - 1) / sf.denom)

rather than
((dim0 + (dim1 * sf.num) + sf.denom - 1) / sf.denom)
2022-01-06 05:26:02 -06:00
DRC
a01857cff6 Build: Disallow NEON_INTRINSICS=0 if GAS is broken
If NEON_INTRINSICS=0, then run the GAS sanity check from libjpeg-turbo
2.0.x and force-enable NEON_INTRINSICS if the test fails.  This fixes
the AArch32 build when using Clang 6.0 on Linux or the Clang toolchain
in the Android NDK r15*-r16*.  It also prevents users from manually
disabling NEON_INTRINSICS if doing so would break the build (such as
with Xcode 5.)
2021-12-01 19:10:14 -06:00
DRC
57ba02a408 Build: Improve Neon capability detection
- Use check_c_source_compiles() rather than check_symbol_exists() to
  detect the presence of vld1_s16_x3(), vld1_u16_x2(), and
  vld1q_u8_x4().  check_symbol_exists() is unreliable for detecting
  intrinsics, and in practice, it did not detect the presence of the
  aforementioned intrinsics in versions of GCC that support them.

- Set DEFAULT_NEON_INTRINSICS=0 for GCC < 12, even if the aforementioned
  intrinsics are available.  The AArch64 back end in GCC 10 and 11
  supports the necessary intrinsics, but the GAS implementation is still
  faster when using those compilers.

Fixes #547
2021-12-01 11:26:57 -06:00
DRC
8a9a6dd15a Make incompatible feature errs more user-friendly
- Use JERR_NOTIMPL ("Not implemented yet") rather than JERR_NOT_COMPILED
  ("Requested feature was omitted at compile time") to indicate that
  arithmetic coding is incompatible with Huffman table optimization.
  This is more consistent with other parts of the libjpeg API code.
  JERR_NOT_COMPILED is typically used to indicate that a major feature
  was not compiled in, whereas JERR_NOTIMPL is typically used to
  indicate that two features were compiled in but are incompatible with
  each other (such as, for instance, two-pass color quantization and
  partial image decompression.)

- Change the text of JERR_NOTIMPL to "Requested features are
  incompatible".  This is a more accurate description of the situation.
  "Not implemented yet" implies that it may be possible to support the
  requested combination of features in the future, but that is not true
  in most of the cases where JERR_NOTIMPL is used.

Fixes #567
2021-12-01 09:43:15 -06:00
DRC
73eff6effe cjpeg: auto. compr. gray BMP/GIF-->grayscale JPEG
aa7459050d was supposed to enable this for
BMP input images but didn't, due to a similar oversight to the one fixed
in the previous commit.
2021-11-30 16:10:23 -06:00
DRC
2ce32e0fe5 cjpeg: automatically compress PGM-->grayscale JPEG
(regression introduced by aa7459050d)

cjpeg sets cinfo.in_color_space to JCS_RGB as an "arbitrary guess."
Since tjLoadImage() never uses JCS_RGB, the PGM reader should treat
JCS_RGB the same as JCS_UNKNOWN.

Fixes #566
2021-11-30 16:09:21 -06:00
DRC
e869a81a7a jdarith.c: Require cinfo->Se == DCTSIZE2 - 1
This fixes an oversight from the integration of the arithmetic entropy
codec from libjpeg (66f97e6820).  I chose
to integrate the latest implementation available at the time, which was
from jpeg-8b.  However, I naively replaced cinfo->lim_Se with
DCTSIZE2 - 1, not realizing that-- because of SmartScale-- jpeg-8b
contains additional code
(https://github.com/libjpeg-turbo/libjpeg-turbo/blob/jpeg-8b/jdinput.c#L249-L334)
that guards against illegal values of cinfo->Se >= DCTSIZE2.  Thus,
libjpeg-turbo's implementation of arithmetic decoding has never guarded
against such illegal values.  This commit restores the relevant check
from the original jpeg-6b arithmetic entropy codec patch ("jpeg-ari",
1e247ac854).

Fixes #564
2021-11-23 10:41:29 -06:00
DRC
5446ff88d6 CI: CIFuzz integration
CIFuzz runs the project's fuzzers for a limited period of time any time
a commit is pushed or a PR is submitted.  This is not intended to
replace OSS-Fuzz but rather to allow us to more quickly catch some
fuzzing failures, including fuzzer build regressions like the one
introduced in ecf021bc0d.

Closes #559
2021-11-19 13:54:07 -06:00
DRC
0f88060b0f cjpeg.c: Fix fuzzer build failure
(caused by previous commit)
2021-11-19 13:36:42 -06:00
DRC
ecf021bc0d cjpeg: Add -strict arg to treat warnings as fatal
This adds fault tolerance to the LZW-compressed GIF reader, which is
the only compression-side code that can throw warnings.
2021-11-18 21:04:35 -06:00
DRC
4c5fa566b3 CI: Halt immediately on all sanitizer errors 2021-11-17 16:09:50 -06:00
Piotr Kubaj
d401d62514 PowerPC: Detect AltiVec support on FreeBSD
Recent FreeBSD/PowerPC compilers, such as Clang 11.0.x on FreeBSD 13, do
the equivalent of passing -maltivec to the compiler by default, so
run-time AltiVec detection is unnecessary.  However, it becomes
necessary when using other compilers or when passing -mno-altivec to the
compiler.

Closes #552
2021-10-30 16:53:51 -05:00
DRC
2fd4ae7b2c JNI: Fix warnings/errors reported by -Xcheck:jni
- Don't check for exceptions immediately after invoking the
  GetPrimitiveArrayCritical() method.  That method does not throw
  exceptions, and checking for them caused -Xcheck:jni to warn about
  calling other JNI functions in the scope of
  Get/ReleasePrimitiveArrayCritical().

- Check for exceptions immediately after invoking the
  CallStaticObjectMethod() method in the PROP2ENV() macro.

- Don't use the Get/ReleasePrimitiveArrayCritical() methods for small
  arrays.  -Xcheck:jni didn't complain about that, but there is no
  performance advantage to using those methods rather than the
  Get*ArrayRegion() methods for small arrays, and using
  Get*ArrayRegion() makes the code less error-prone.

- Don't release the source/destination planes arrays in the YUV methods
  until after the corresponding C TurboJPEG functions have returned.
2021-10-27 14:50:22 -05:00
Ash Kyd
5552483db9 Fix typo in readme 2021-10-14 11:40:48 +01:00
Alex Xu (Hello71)
18edeff4e8 Build: Set CMP0065 NEW (respect ENABLE_EXPORTS)
Referring to https://cmake.org/cmake/help/latest/policy/CMP0065.html,
CMake 3.3 and earlier automatically added compiler/linker flags such as
-rdynamic/-export-dynamic, which caused symbols to be exported from
executables.  The primary purpose of this is to allow plugins loaded via
dlopen() to access symbols from the calling program.  libjpeg-turbo
does not need this functionality, and enabling it needlessly increases
the size of the libjpeg-turbo executables.

Setting CMP0065 to NEW when using CMake 3.4 and later prevents CMake
from automatically adding the aforementioned compiler/linker flags
unless the ENABLE_EXPORTS property is set for a target (or the
CMAKE_ENABLE_EXPORTS variable is set, which causes ENABLE_EXPORTS to be
set for all targets.)

Closes #554
2021-10-03 13:39:38 -05:00
DRC
a9c41fbc4f Build: Don't enable Neon SIMD exts with Armv6-
When building for 32-bit Arm platforms, test whether basic Neon
intrinsics will compile with the specified compiler and C flags.  This
prevents the build system from enabling the Neon SIMD extensions when
targetting Armv6 and other legacy architectures that do not support Neon
instructions.

Regression introduced by bbd8089297.
(Checking whether gas-preprocessor.pl was needed for 32-bit Arm builds
had the effect of checking whether Neon instructions were supported.)

Fixes #553
2021-10-03 13:10:35 -05:00
DRC
739ecbc5ec ChangeLog.md: List CVE ID fixed by 2849d86a 2021-09-30 16:28:51 -05:00
DRC
4c313544e2 AppVeyor: Deploy artifacts to Amazon S3
We would have been perfectly happy for AppVeyor to delete all artifacts
other than those from the latest builds in each branch.  Instead, they
chose to change the global artifact retention policy to 1 month.  In
addition to being unworkable, that new policy uses more storage than the
policy we requested.  Lose/lose, so we'll just deploy to S3 like we do
with other platforms.
2021-09-20 17:12:02 -05:00
DRC
173900b1ca tjTrans: Allow 8x8 crop alignmnt w/odd 4:4:4 JPEGs
Fixes #549
2021-09-02 13:31:11 -05:00
DRC
5d2430f4da ChangeLog.md: Add missing sub-header for 2.1.2 2021-09-02 13:18:10 -05:00
DRC
129f0cb763 Neon/AArch64: Don't put GAS functions in .rodata
Regression introduced by 240ba417aa

Closes #546
2021-08-25 12:54:24 -05:00
DRC
0a9b972178 jmemmgr.c: Pass correct size arg to jpeg_free_*()
This issue was introduced in 5557fd2217
due to an oversight, so it has existed in libjpeg-turbo since the
project's inception.  However, the issue is effectively a non-issue.
Although #325 proposes allowing programs to override jpeg_get_*() and
jpeg_free_*() externally, there is currently no way to override those
functions without modifying the libjpeg-turbo source code.
libjpeg-turbo only includes the malloc()/free() memory manager from
libjpeg, and the implementation of jpeg_free_*() in that memory manager
ignores the size argument.  libjpeg had several additional memory
managers for legacy systems (MS-DOS, System 7, etc.), but those memory
managers ignored the size argument to jpeg_free_*() as well.  Thus, this
issue would have only potentially affected custom memory managers in
downstream libjpeg-turbo forks, and since no one has complained until
now, apparently those are rare.

Fixes #542
2021-08-09 18:16:57 -05:00
DRC
2849d86aaa SSE2/64-bit: Fix trans. segfault w/ malformed JPEG
Attempting to losslessly transform certain malformed JPEG images can
cause the nbits table index in the Huffman encoder to exceed 32768, so
we need to pad the SSE2 implementation of that table to 65536 entries as
we do with the C implementation.

Regression introduced by 087c29e07f

Fixes #543
2021-08-06 14:04:34 -05:00
DRC
84d6306f64 Fix build w/CMake 3.14+ when CMAKE_SYSTEM_NAME=iOS
Closes #539
2021-07-27 11:26:51 -05:00
Kornel
512a7c3a51 Merge tag '2.1.0'
* tag '2.1.0': (39 commits)
  TurboJPEG: Update JPEG buf ptrs on comp/xform err
  Include TJ.FLAG_LIMITSCANS in JNI header
  OSS-Fuzz: Code comment tweaks for compr. targets
  jdhuff.h: Fix ASan regression caused by 8fa70367
  cjpeg_fuzzer: Add cov for h2v2 smooth downsampling
  Huff decs: Fix/suppress more innocuous UBSan errs
  Huff dec: Fix non-deterministic output w/bad input
  OSS-Fuzz: Check img size b4 readers allocate mem
  OSS-Fuzz: More code coverage improvements
  jchuff.c: Fix MSan error
  compress_yuv_fuzzer: Minor code coverage tweak
  cjpeg.c: Code formatting tweak
  rdbmp.c: Fix more innocuous UBSan errors
  rdbmp.c/rdppm.c: Fix more innocuous UBSan errors
  OSS-Fuzz: cjpeg fuzz target
  compress_yuv_fuzzer: Use unique filename template
  OSS-Fuzz: Fix UBSan err caused by TJFLAG_FUZZING
  OSS-Fuzz: YUV encoding/compression fuzz target
  ...
2021-07-21 22:39:01 +01:00
y-guyon
e6e952d5d5 Suppress UBSan error in decode_mcu_fast()
This is the same error that d147be83e9
suppressed in decode_mcu_slow().  The image that reproduces this error
in decode_mcu_fast() has been added to the libjpeg-turbo seed corpora.

Closes #537
2021-07-16 12:58:00 -05:00
Alex Richardson
a72816ed07 Use uintptr_t, if avail, for pointer-to-int casts
Although sizeof(void *) == sizeof(size_t) for all architectures that are
currently supported by libjpeg-turbo, such is not guaranteed by the C
standard.  Specifically, CHERI-enabled architectures (e.g. CHERI-RISC-V
or Arm's Morello) use capability pointers that are twice the size of
size_t (128 bits for Morello and RV64), so casting to size_t strips the
upper bits of the pointer (including the validity bit) and makes it
non-deferenceable, as indicated by the following compiler warning:

  warning: cast from provenance-free integer type to pointer type will
  give pointer that can not be dereferenced
  [-Werror,-Wcheri-capability-misuse]
    cvalue = values = (JCOEF *)PAD((size_t)values_unaligned, 16);

Ignoring this warning results in a run-time crash.  Casting pointers to
uintptr_t, if it is available, avoids this problem, since uintptr_t is
defined as an unsigned integer type that can hold a pointer value.

Since C89 compatibility is still necessary in libjpeg-turbo, this commit
introduces a new typedef for pointer-to-integer casts that uses a
GNU-specific extension available in GCC 4.6+ and Clang 3.0+ and falls
back to using size_t if the extension is unavailable.  The only other
options would require C99 or Clang-specific builtins.

Closes #538
2021-07-16 12:23:29 -05:00
DRC
4d9f256b01 jpegtran: Add option to copy only ICC markers
Closes #533
2021-07-13 11:54:31 -05:00
Peter Kasting
b201838d8b Neon: Silence -Wimplicit-fallthrough warnings
Refer to https://bugs.chromium.org/p/chromium/issues/detail?id=995993

Closes #534
2021-07-13 10:21:38 -05:00
DRC
a1bfc05854 Neon/AArch32: Mark inline asm output as read/write
'buffer' is both passed into the inline assembly code and modified by
it.  See https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html, 6.47.2.3.

With GCC 4, this commit does not change the generated assembly code at
all.

With GCC 8, this commit fixes an assembly error:

  /tmp/{foo}.s: Assembler messages:
  /tmp/{foo}.s:775: Error: registers may not be the same --
                    `str r9,[r9],#4'

I'm not sure why that error went unnoticed, since I definitely
benchmarked the previous commit with GCC 8.  Anyhow, this commit changes
the generated assembly code slightly but does not alter performance.

With Clang 10, this commit changes the generated assembly code slightly
but does not alter performance.

Refer to #529
2021-07-12 15:22:24 -05:00
DRC
2a2970af67 Neon/AArch32: Work around Clang T32 miscompilation
Referring to the C standard
(http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf,
J.2 Undefined behavior), the behavior of the compiler is undefined if
"conversion between two pointer types produces a result that is
incorrectly aligned."  Thus, the behavior of this code

  *((uint32_t *)buffer) = BUILTIN_BSWAP32(put_buffer);

in the AArch32 version of the FLUSH() macro is undefined unless 'buffer'
is 32-bit-aligned.  Referring to
https://bugs.llvm.org/show_bug.cgi?id=50785, certain versions of Clang,
when generating Thumb (T32) instructions, miscompile that code into an
assembly instruction (stm) that requires the destination to be
32-bit-aligned.  Since such alignment cannot be guaranteed within the
Huffman encoder, this reportedly led to crashes (SIGBUS: illegal
alignment) with AArch32/Thumb builds of libjpeg-turbo running on Android
devices, although thus far I have been unable to reproduce those crashes
with a plain Linux/Arm system.

The miscompilation is visible with the Compiler Explorer:
https://godbolt.org/z/rv1ccx1Pb
However, it goes away when removing the return statement from the
function.  Thus, it seems that Clang's behavior in this regard is
somewhat variable, which may explain why the crashes are only
reproducible on certain platforms.

The suggested workaround is to use memcpy(), but whereas Clang and
recent GCC releases are smart enough to compile a 4-byte memcpy() call
into a str instruction, GCC < 6 is not.  Referring to
https://godbolt.org/z/ae7Wje3P6, the only way to consistently produce
the desired str instruction across all supported compilers is to use
inline assembly.  Visual C++ presumably does not miscompile the code in
question, since no issues have been reported with it, but since the code
relies on undefined compiler behavior, prudence dictates that
e4ec23d7ae should be reverted for Visual
C++, which this commit does.  The performance impact of
e4ec23d7ae for Visual C++/Arm builds is
unknown (I have no ability to test such builds), but regardless, this
commit reverts the Visual C++/Arm performance to that of libjpeg-turbo
2.1 beta1.

Closes #529
2021-07-09 19:37:58 -05:00
DRC
97a1575cb8 RPM: Don't include system lib dir in file list
This resolves a conflict between the RPM generated by the libjpeg-turbo
build system and the Red Hat 'filesystem' RPM if
CMAKE_INSTALL_LIBDIR=/usr/lib[64].  This code was largely borrowed from
the VirtualGL RPM spec.  (I can legally do that because I hold the
copyright on VirtualGL's implementation.)

Fixes #532
2021-07-07 14:51:09 -05:00
DRC
0081c2de20 Neon/AArch32: Fix build if 'soft' float ABI used
Arm compilers have three floating point ABI options:

'soft' compiles floating point operations as function calls into a
software floating point library, which emulates floating point
operations using integer operations.  Floating point function arguments
are passed using integer registers.

'softfp' also compiles floating point operations as function calls into
a floating point library and passes floating point function arguments
using integer registers, but the floating point library functions can
use FPU instructions if the CPU supports them.

'hard' compiles floating point operations into inline FPU instructions,
similarly to x86 and other architectures, and passes floating point
function arguments using FPU registers.

Not all AArch32 CPUs have FPUs or support Neon instructions, so on Linux
and Android platforms, the AArch32 SIMD dispatcher in libjpeg-turbo only
enables the Neon SIMD extensions at run time if /proc/cpuinfo indicates
that the CPU supports Neon instructions or if Neon instructions are
explicitly enabled (e.g. by passing -mfpu=neon to the compiler.)  In
order to support all AArch32 CPUs using the same code base, i.e. to
support run-time FPU and Neon auto-detection, it is necessary to compile
the scalar C source code using -mfloat-abi=soft.  However, the 'soft'
floating point ABI cannot be used when compiling Neon intrinsics, so the
intrinsics implementation of the Neon SIMD extensions must be compiled
using -mfloat-abi=softfp if the scalar C source code is compiled using
-mfloat-abi=soft.

This commit modifies the build system so that it detects whether
-mfloat-abi=softfp must be explicitly added to the compiler flags when
building the intrinsics implementation of the Neon SIMD extensions.
This will be necessary if the build is using the 'soft' floating
point ABI along with run-time auto-detection of Neon instructions.

Fixes #523
2021-07-07 14:10:05 -05:00
Peter Kasting
9df5786f05 Fix -Wimplicit-fallthrough warnings with Clang
The existing /*FALLTHROUGH*/ comments work with GCC but not Clang, so
this commit adds a FALLTHROUGH macro that uses the 'fallthrough'
attribute if the compiler supports it.

Refer to https://bugs.chromium.org/p/chromium/issues/detail?id=995993

NOTE: All versions of GCC that support -Wimplicit-fallthrough also
support the 'fallthrough' attribute, but certain other compilers (Oracle
Solaris Studio, for instance) support /*FALLTHROUGH*/ but not the
'fallthrough' attribute.  Thus, this commit retains the /*FALLTHROUGH*/
comments, which have existed in the libjpeg code base in some form since
1994 (libjpeg v5.)

Closes #531
2021-07-06 12:37:34 -05:00
tasty0tomato
323469818c Add building libpng in Windows 2021-06-22 15:47:29 +01:00
DRC
1a1fb615db ChangeLog.md: List CVE ID fixed by c76f4a08
Referring to #527, the security community did not assign this CVE ID
until more than 8 months after the fix for the issue was released.  By
the time they assigned the ID, libjpeg-turbo already had two production
releases containing the fix.  This calls into question the usefulness of
assigning a CVE ID to the issue, particularly given that the buffer
overrun in question was fully contained in the stack, not detectable
with valgrind, and confined to lossless transformation (it did not
affect JPEG compression or decompression.)

https://vuldb.com/?id.176175
says that "the exploitability is told to be easy" but provides no
clarification, and given that the author of that page does not seem to
be aware that a fix for the issue has been available since early
December of 2019, it calls into question the accuracy of everything else
on the page.

It would really be nice if the security community approached me about
these things before wasting my time, but I guess it's my lot in life to
modify a change log entry from 2019 to include a CVE ID from 2020.

So it goes...
2021-06-18 10:29:12 -05:00
DRC
5135c2e25d Build: Use PIC for jsimd_none.o in shared libs
In theory, all objects that will be included in a Un*x shared library
must be built using PIC.  In practice, most compilers don't require PIC
to be explicitly specified for jsimd_none.o, either because the compiler
automatically enables PIC in all cases (Ubuntu) or because the size of
the generated object is too small.  But some rare compilers do require
PIC to be explicitly specified for jsimd_none.o.

Fixes #520
2021-05-28 13:09:43 -05:00
DRC
3932190c2e Fix build w/ non-GCC-compatible Un*x/Arm compilers
Regression introduced by d2c4079959

Closes #519
2021-05-17 13:09:37 -05:00
DRC
a219fd13b0 GitHub bug-report.md: "master" branch --> "main" 2021-05-12 10:58:59 -05:00
DRC
c23672ce52 GitHub Actions: Don't build tags
Our workflow script does not currently work with tags, and there is no
point to building tags anyhow, since we do not use the CI system to spin
official builds.
2021-04-23 13:29:40 -05:00
DRC
4f51f36eb3 Bump version to 2.1.0 to prepare for final release 2021-04-23 11:42:40 -05:00
DRC
e0606dafff TurboJPEG: Update JPEG buf ptrs on comp/xform err
When using the in-memory destination manager, it is necessary to
explicitly call the destination manager's term_destination() method if
an error occurs.  That method is called by jpeg_finish_compress() but
not by jpeg_abort_compress().

This fixes a potential double free() that could occur if tjCompress*()
or tjTransform() returned an error and the calling application tried to
clean up a JPEG buffer that was dynamically re-allocated by one of those
functions.
2021-04-21 15:42:00 -05:00
DRC
ffc1aa9674 Include TJ.FLAG_LIMITSCANS in JNI header
(oversight from c81e91e8ca)

This is purely cosmetic, since the JNI wrapper doesn't actually use that
flag.
2021-04-21 12:33:00 -05:00
DRC
55ec9b3b89 OSS-Fuzz: Code comment tweaks for compr. targets
(oversight from 171b875b27)
2021-04-21 12:33:00 -05:00
DRC
4de8f6922a jdhuff.h: Fix ASan regression caused by 8fa70367
The 0xFF is, in fact, necessary.
2021-04-16 16:34:12 -05:00
DRC
785ec30eb4 cjpeg_fuzzer: Add cov for h2v2 smooth downsampling 2021-04-16 15:59:38 -05:00
DRC
d147be83e9 Huff decs: Fix/suppress more innocuous UBSan errs
- UBSan complained that entropy->restarts_to_go was underflowing an
  unsigned integer when it was decremented while
  cinfo->restart_interval == 0.  That was, of course, completely
  innocuous behavior, since the result of the underflowing computation
  was never used.

- d3a3a73f64 and
  7bc9fca430 silenced a UBSan signed
  integer overflow error, but unfortunately other malformed JPEG images
  have been discovered that cause unsigned integer overflow in the same
  computation.  Since, to the best of our understanding, this behavior
  is innocuous, this commit reverts the commits listed above, suppresses
  the UBSan errors, and adds code comments to document the issue.
2021-04-15 23:46:15 -05:00
DRC
8fa70367ed Huff dec: Fix non-deterministic output w/bad input
Referring to https://bugzilla.mozilla.org/show_bug.cgi?id=1050342,
there are certain very rare circumstances under which a malformed JPEG
image can cause different Huffman decoder output to be produced,
depending on the size of the source manager's I/O buffer.  (More
specifically, the fast Huffman decoder didn't handle invalid codes in
the same manner as the slow decoder, and since the fast decoder requires
all data to be memory-resident, the buffering strategy determines
whether or not the fast decoder can be used on a particular MCU block.)

After extensive experimentation, the Mozilla and Chrome developers and I
determined that this truly was an innocuous issue.  The patch that both
browsers adopted as a workaround caused a performance regression with
32-bit code, which is why it was not accepted into libjpeg-turbo.  This
commit fixes the problem in a less disruptive way with no performance
regression.
2021-04-15 22:55:50 -05:00
DRC
171b875b27 OSS-Fuzz: Check img size b4 readers allocate mem
After the completion of the start_input() method, it's too late to check
the image size, because the image readers may have already tried to
allocate memory for the image.  If the width and height are excessively
large, then attempting to allocate memory for the image could slow
performance or lead to out-of-memory errors prior to the fuzz target
checking the image size.

NOTE: Specifically, the aforementioned OOM errors and slow units were
observed with the compression fuzz targets when using MSan.
2021-04-15 21:20:33 -05:00
DRC
3ab3234875 OSS-Fuzz: More code coverage improvements 2021-04-13 11:58:20 -05:00
DRC
3e68a5ee20 jchuff.c: Fix MSan error
Certain rare malformed input images can cause the Huffman encoder to
generate a value for nbits that corresponds to an uninitialized member
of the DC code table.  The ramifications of this are minimal and would
basically amount to a different bogus JPEG image being generated from a
particular bogus input image.
2021-04-12 14:37:43 -05:00
DRC
4e45161654 compress_yuv_fuzzer: Minor code coverage tweak 2021-04-12 11:53:29 -05:00
DRC
629e96eedc cjpeg.c: Code formatting tweak 2021-04-12 11:52:55 -05:00
DRC
ebaa67ea32 rdbmp.c: Fix more innocuous UBSan errors
- Referring to 3311fc0001, we need to use
  unsigned intermediate math in order to make UBSan happy, even though
  (JDIMENSION)(A * B) is effectively the same as
  (JDIMENSION)A *(JDIMENSION)B, regardless of intermediate overflow.

- Because of the previous commit, it is now possible for bfOffBits to be
  INT_MIN, which would cause the initial computation of bPad to
  underflow a signed integer.  Thus, we need to check for that
  possibility as soon as we know the values of bfOffBits and headerSize.
  The worst case from this regression is that bPad could wrap around to
  a large positive value, which would cause a "Premature end of input
  file" error in the subsequent read_byte() loop.  Thus, this issue was
  effectively innocuous as well, since it resulted in catching the same
  error later and in a different way.  Also, the issue was very
  well-contained, since it was both introduced and fixed as part of the
  ongoing OSS-Fuzz integration project.
2021-04-12 11:48:14 -05:00
DRC
dd830b3ffe rdbmp.c/rdppm.c: Fix more innocuous UBSan errors
- rdbmp.c: Because of 8fb37b8171,
  bfOffBits, biClrUsed, and headerSize were made into unsigned ints.
  Thus, if bPad would eventually be negative due to a malformed header,
  UBSan complained about unsigned math being used in the intermediate
  computations.  It was unnecessary to make those variables unsigned,
  since they are only meant to hold small values, so this commit makes
  them signed again.  The UBSan error was innocuous, because it is
  effectively (if not officially) the case that
  (int)((unsigned int)a - (unsigned int)b) == (int)a - (int)b.

- rdbmp.c: If (biWidth * source->bits_per_pixel / 8) would overflow an
  unsigned int, then UBSan complained at the point at which row_width
  was set in start_input_bmp(), even though the overflow would have been
  detected later in the function.  This commit adds overflow checks
  prior to setting row_width.

- rdppm.c: read_pbm_integer() now bounds-checks the intermediate
  value computations in order to catch integer overflow caused by a
  malformed text PPM.  It's possible, though extremely unlikely, that
  the intermediate value computations could have wrapped around to a
  value smaller than maxval, but the worst case is that this would have
  generated a bogus pixel in the uncompressed image rather than throwing
  an error.
2021-04-09 20:09:04 -05:00
DRC
4ede2ef523 OSS-Fuzz: cjpeg fuzz target 2021-04-09 19:27:22 -05:00
DRC
5cda8c5e31 compress_yuv_fuzzer: Use unique filename template 2021-04-09 13:12:32 -05:00
DRC
47b66d1d1e OSS-Fuzz: Fix UBSan err caused by TJFLAG_FUZZING 2021-04-09 11:26:34 -05:00
DRC
55ab0d396c OSS-Fuzz: YUV encoding/compression fuzz target 2021-04-08 16:13:06 -05:00
DRC
18bc4c6114 compress.cc: Code formatting tweak 2021-04-07 16:08:59 -05:00
DRC
b1079002ad rdppm.c: Fix innocuous MSan error
A fuzzing test case that was effectively a 1-pixel PGM file with a
maximum value of 1 and an actual value of 8 caused an uninitialized
member of the rescale[] array to be accessed in get_gray_rgb_row() or
get_gray_cmyk_row().  Since, for performance reasons, those functions do
not perform bounds checking on the PPM values, we need to ensure that
unused members of the rescale[] array are initialized.
2021-04-07 16:08:48 -05:00
DRC
3311fc0001 rdbmp.c: Fix innocuous UBSan error
A fuzzing test case with an image width of 838860946 triggered a UBSan
error:

rdbmp.c:633:34: runtime error: signed integer overflow:
838860946 * 3 cannot be represented in type 'int'

Because the result is cast to an unsigned int (JDIMENSION), this error
is irrelevant, because

(unsigned int)((int)838860946 * (int)3) ==
(unsigned int)838860946 * (unsigned int)3
2021-04-07 15:23:32 -05:00
DRC
34d264d64e OSS-Fuzz: Private TurboJPEG API flag for fuzzing
This limits the tjLoadImage() behavioral changes to the scope of the
compress_fuzzer target.  Otherwise, TJBench in fuzzer builds would
refuse to load images larger than 1 Mpixel.
2021-04-07 15:09:29 -05:00
DRC
f35fd27ec6 tjLoadImage: Fix issues w/loading 16-bit PPMs/PGMs
- The PPM reader now throws an error rather than segfaulting (due to a
  buffer overrun) if an application attempts to load a 16-bit PPM file
  into a grayscale uncompressed image buffer.  No known applications
  allowed that (not even the test applications in libjpeg-turbo),
  because that mode of operation was never expected to work and did not
  work under any circumstances.  (In fact, it was necessary to modify
  TJBench in order to reproduce the issue outside of a fuzzing
  environment.)  This was purely a matter of making the library bow out
  gracefully rather than crash if an application tries to do something
  really stupid.

- The PPM reader now throws an error rather than generating incorrect
  pixels if an application attempts to load a 16-bit PGM file into an
  RGB uncompressed image buffer.

- The PPM reader now correctly loads 16-bit PPM files into extended
  RGB uncompressed image buffers.  (Previously it generated incorrect
  pixels unless the input colorspace was JCS_RGB or JCS_EXT_RGB.)

The only way that users could have potentially encountered these issues
was through the tjLoadImage() function.  cjpeg and TJBench were
unaffected.
2021-04-06 16:12:29 -05:00
DRC
df17d398ec jcphuff.c: -Wjump-misses-init warning w/GCC 9 -m32
(verified that this commit does not change the generated 64-bit or
32-bit assembly code)
2021-04-06 14:11:32 -05:00
DRC
cd9a318502 Bump TurboJPEG C API version to 2.1
(because of TJFLAG_LIMITSCANS)
2021-04-05 22:20:52 -05:00
DRC
d2d4465548 OSS-Fuzz: Compression fuzz target 2021-04-05 21:59:11 -05:00
DRC
5536ace198 OSS-Fuzz: Fix C++11 compiler warnings in targets 2021-04-05 21:12:29 -05:00
DRC
5dd906beff OSS-Fuzz: Test non-default opts w/ decompress_yuv
The non-default options were not being tested because of a pixel format
comparison buglet.  This commit also changes the code in both
decompression fuzz targets such that non-default options are tested
based on the pixel format index rather than the pixel format value,
which is a bit more idiot-proof.
2021-04-05 17:53:15 -05:00
DRC
c81e91e8ca TurboJPEG: New flag for limiting prog JPEG scans
This also fixes timeouts reported by OSS-Fuzz.
2021-04-05 16:33:44 -05:00
DRC
bff7959e34 OSS-Fuzz: Require static libraries
Refer to
https://google.github.io/oss-fuzz/further-reading/fuzzer-environment/#runtime-dependencies
for the reasons why this is necessary.
2021-04-02 14:58:55 -05:00
DRC
6ad658be17 OSS-Fuzz: Build fuzz targets using C++ compiler
Otherwise, the targets will require libstdc++, the i386 version of which
is not available in the OSS-Fuzz runtime environment.  The OSS-Fuzz
build environment passes -stdlib:libc++ in the CXXFLAGS environment
variable in order to mitigate this issue, since the runtime environment
has the i386 version of libc++, but using that compiler flag requires
using the C++ compiler.
2021-04-02 14:58:31 -05:00
DRC
7b57cba6b4 OSS-Fuzz: Fix uninitialized reads detected by MSan 2021-04-01 11:30:24 -05:00
DRC
2f9e8a1172 OSS-Fuzz integration
This commit integrates OSS-Fuzz targets directly into the libjpeg-turbo
source tree, thus obsoleting and improving code coverage relative to
Google's OSS-Fuzz target for libjpeg-turbo (previously available here:
https://github.com/google/oss-fuzz).

I hope to eventually create fuzz targets for the BMP, GIF, and PPM
readers as well, which would allow for fuzz-testing compression, but
since those readers all require an input file, it is unclear how to
build an efficient fuzzer around them.  It doesn't make sense to
fuzz-test compression in isolation, because compression can't accept
arbitrary input data.
2021-03-30 20:59:41 -05:00
Jonathan Wright
e4ec23d7ae Neon: Use byte-swap builtins instead of inline asm
Define compiler-independent byte-swap macros and use them instead of
executing 'rev' via inline assembly code with GCC-compatible compilers
or a slow shift-store sequence with Visual C++.

* This produces identical assembly code with:

  - 64-bit GCC 8.4.0 (Linux)
  - 64-bit GCC 9.3.0 (Linux)
  - 64-bit Clang 10.0.0 (Linux)
  - 64-bit Clang 10.0.0 (MinGW)
  - 64-bit Clang 12.0.0 (Xcode 12.2, macOS)
  - 64-bit Clang 12.0.0 (Xcode 12.2, iOS)

* This produces different assembly code with:

  - 64-bit GCC 4.9.1 (Linux)
  - 32-bit GCC 4.8.2 (Linux)
  - 32-bit GCC 8.4.0 (Linux)
  - 32-bit GCC 9.3.0 (Linux)
    Since the intrinsics implementation of Huffman encoding is not used
    by default with these compilers, this is not a concern.

  - 32-bit Clang 10.0.0 (Linux)
    Verified performance neutrality

Closes #507
2021-03-26 14:09:10 -05:00
DRC
e795afc330 SSE2: Fix prog Huff enc err if Sl%32==0 && Al!=0
(regression introduced by 16bd984557)

This implements the same fix for
jsimd_encode_mcu_AC_refine_prepare_sse2() that
a81a8c137b implemented for
jsimd_encode_mcu_AC_first_prepare_sse2().

Based on:
1a59587397
eb176a91d8

Fixes #509
Closes #510
2021-03-25 22:46:14 -05:00
Adrian Bunk
2c01200c5d Build: Fix incorrect regexes w/ if(...MATCHES...)
"arm*" as a regex means 'ar' followed by zero or more 'm' characters,
which matches 'parisc' and 'sparc64' as well.
2021-03-15 12:56:53 -05:00
DRC
ed70101da2 ChangeLog.md: List CVE ID fixed by 1719d12e
Referring to https://bugzilla.redhat.com/show_bug.cgi?id=1937385#c2,
it is my opinion that the severity of this bug was grossly overstated
and that a CVE never should have been assigned to it, but since one was
assigned, users need to know which version of libjpeg-turbo contains
the fix.

Dear security community, please learn what "DoS" actually means and stop
misusing that term for dramatic effect.  Thanks.
2021-03-15 12:36:55 -05:00
Kornel
c78b82bbb1 Merge error 2021-03-01 11:31:05 +00:00
Kornel
886ddb1786 Merge commit '8a2cad020171184a49fa8696df0b9e267f1cf2f6'
* commit '8a2cad020171184a49fa8696df0b9e267f1cf2f6': (99 commits)
  Build: Handle CMAKE_OSX_ARCHITECTURES=(i386|ppc)
  Add Sponsor button for GitHub repository
  Build: Support CMAKE_OSX_ARCHITECTURES
  cjpeg: Fix FPE when compressing 0-width GIF
  Fix build with Visual C++ and /std:c11 or /std:c17
  Neon: Fix Huffman enc. error w/Visual Studio+Clang
  Use CLZ compiler intrinsic for Windows/Arm builds
  Build: Use correct SIMD exts w/VStudio IDE + Arm64
  jcphuff.c: Fix compiler warning with clang-cl
  Migrate from Travis CI to GitHub Actions
  tjexample.c: Fix mem leak if tjTransform() fails
  Build: Officially support Ninja
  decompress_smooth_data(): Fix another uninit. read
  LICENSE.md: Remove trailing whitespace
  Build: Test for correct AArch32 RPM/DEBARCH value
  LICENSE.md: Formatting tweak
  Fix uninitialized read in decompress_smooth_data()
  Fix buffer overrun with certain narrow prog JPEGs
  Bump revision to 2.0.91 for post-beta fixes
  Travis: Use Docker tag that matches Git branch
  ...
2021-02-26 21:30:09 +00:00
Ewout ter Hoeven
69bd7ed953 AppVeyor: Update to Visual Studio 2019 image
Updates the AppVeyor build environment, see https://www.appveyor.com/docs/build-environment/#build-worker-images for more information
2021-02-25 23:50:41 +00:00
Kornel
ed21c3ba6f Bump 2021-02-25 22:09:13 +00:00
Kornel
9f01177f72 Default to single-scan DC
People don't like green faces
2021-02-25 21:44:09 +00:00
Kornel
ceb4f8e97c Microsoft's C stdlib continues to be a disappointment 2021-01-24 23:08:26 +00:00
Kornel
44f3f8a544 Fudge incompatible turbo tests 2021-01-22 18:44:39 +00:00
Kornel
fe0e3c7e88 Merge commit '10ba6ed3365615ed5c2995fe2d240cb2d5000173'
* commit '10ba6ed3365615ed5c2995fe2d240cb2d5000173': (32 commits)
  Travis: Install MacPorts without using macports-ci
  Build: Set FLOATTEST more intelligently
  BUILDING.md: Use min. iOS v8 in iOS Armv8 example
  Fix build if WITH_12BIT==1 && WITH_JPEG(7|8)==1
  Travis: Combine PPC/Arm tests with jpeg-7/8 tests
  Build: Fix test failures w/ Arm Neon SIMD exts
  Travis: Regression-test Armv8 and PPC SIMD exts
  Demote "fast" [I]DCT algorithms to legacy status
  jpegtran.c: "subarea" = "region"
  jpegtran.1: Minor formatting tweak
  transupp.c: Code formatting tweaks
  cdjpeg.h: Remove unused function stub
  Consistify formatting to simplify checkstyle
  README.ijg: Update URLs; remove Usenet info
  jversion.h: Update copyrights
  Build: Improve Arm 32-bit cross-comp./packaging
  "ARM"="Arm", "NEON"="Neon"
  Build: Fix permissions
  ChangeLog: Fix minor formatting issue
  ChangeLog.md: jpeg_crop_scanline(), not scanlines
  ...
2021-01-22 16:03:54 +00:00
DRC
8a2cad0201 Build: Handle CMAKE_OSX_ARCHITECTURES=(i386|ppc)
We don't officially support i386 or PowerPC Mac builds of libjpeg-turbo
anymore, but they still work (bearing in mind that PowerPC builds
require GCC v4.0 in Xcode 3.2.6, and i386 builds require Xcode 9.x or
earlier.)  Referring to #495, apparently MacPorts needs this
functionality.
2021-01-21 10:51:49 -06:00
DRC
b6772910d3 Add Sponsor button for GitHub repository 2021-01-19 15:32:32 -06:00
DRC
399aa374bd Build: Support CMAKE_OSX_ARCHITECTURES
... as long as it contains only a singular value, which must equal
"x86_64" or "arm64".

Refer to #495
2021-01-19 12:25:11 -06:00
DRC
1719d12e51 cjpeg: Fix FPE when compressing 0-width GIF
Fixes #493
2021-01-14 18:38:06 -06:00
DRC
486cdcfb9d Fix build with Visual C++ and /std:c11 or /std:c17
Fixes #481
Closes #482
2021-01-12 17:45:55 -06:00
Richard Townsend
74e6ea45e3 Neon: Fix Huffman enc. error w/Visual Studio+Clang
The GNU builtin function __builtin_clzl() accepts an unsigned long
argument, which is 8 bytes wide on LP64 systems (most Un*x systems,
including Mac) but 4 bytes wide on LLP64 systems (Windows.)  This caused
the Neon intrinsics implementation of Huffman encoding to produce
mathematically incorrect results when compiled using Visual Studio with
Clang.

This commit changes all invocations of __builtin_clzl() in the Neon SIMD
extensions to __builtin_clzll(), which accepts an unsigned long long
argument that is guaranteed to be 8 bytes wide on all systems.

Fixes #480
Closes #490
2021-01-11 22:29:11 -06:00
Jonathan Wright
d2c4079959 Use CLZ compiler intrinsic for Windows/Arm builds
The __builtin_clz() compiler intrinsic was already used in the C Huffman
encoders when building libjpeg-turbo for Arm CPUs using a GCC-compatible
compiler.  This commit modifies the C Huffman encoders so that they also
use__builtin_clz() when building for Arm CPUs using Visual Studio +
Clang, as well as the equivalent _CountLeadingZeros() compiler intrinsic
when building for Arm CPUs using Visual C++.

In addition to making the C Huffman encoders faster on Windows/Arm, this
also prevents jpeg_nbits_table from being included in Windows/Arm builds,
thus saving 128 KB of memory.
2021-01-11 17:10:38 -06:00
DRC
3e8911aad5 Build: Use correct SIMD exts w/VStudio IDE + Arm64
When configuring a Visual Studio IDE build and passing -A arm64 to
CMake, CMAKE_SYSTEM_PROCESSOR will be amd64, so we should set CPU_TYPE
based on the value of CMAKE_GENERATOR_PLATFORM rather than the value of
CMAKE_SYSTEM_PROCESSOR.
2021-01-11 14:03:42 -06:00
DRC
4b838c38f9 jcphuff.c: Fix compiler warning with clang-cl
Fixes #492
2021-01-11 13:45:25 -06:00
DRC
944f5915cd Migrate from Travis CI to GitHub Actions
Note that this removes our ability to regression test the Armv8 and
PowerPC SIMD extensions, effectively reverting
a524b9b06b and
02227e48a9, but at the moment, there is no
other way.
2021-01-08 14:20:44 -06:00
DRC
3179f330b2 tjexample.c: Fix mem leak if tjTransform() fails
Fixes #479
2021-01-04 15:39:35 -06:00
DRC
1388ad6757 Build: Officially support Ninja 2020-12-08 21:25:47 -06:00
DRC
110d8d6dca decompress_smooth_data(): Fix another uninit. read
Regression introduced by 42825b68d5

The test case
https://user-images.githubusercontent.com/3491627/101376530-fde56180-38b0-11eb-938d-734119a5b5ba.jpg
is a malformed progressive JPEG image containing an interleaved Y/Cb/Cr
DC scan followed by two non-interleaved Y DC scans.  Thus, the
prev_coef_bits[] array was initialized for the Y component but not the
other components, the uninitialized values for Cb and Cr were
transferred to the prev_coef_bits_latch[] array in smoothing_ok(), and
because cinfo->master->last_good_iMCU_row was 0,
decompress_smooth_data() read those uninitialized values when attempting
to smooth the second iMCU row.

Possibly fixes #478
2020-12-07 12:51:26 -06:00
DRC
7b68764905 LICENSE.md: Remove trailing whitespace
Use <br> to indicate a line break, as we do in README.md, in order to
make checkstyle happy.
2020-12-03 21:20:42 -06:00
DRC
21d056847b Build: Test for correct AArch32 RPM/DEBARCH value
... based on the floating point ABI being used by the compiler (which
do you choose, a hard or soft option?)
2020-12-03 21:20:08 -06:00
DRC
6e4509a3f1 LICENSE.md: Formatting tweak 2020-12-01 09:04:27 -06:00
DRC
c7ca521bc8 Fix uninitialized read in decompress_smooth_data()
Regression introduced by 42825b68d5

Referring to the discussion in #459, the OSS-Fuzz test case
https://github.com/libjpeg-turbo/libjpeg-turbo/files/5597075/clusterfuzz-testcase-minimized-pngsave_buffer_fuzzer-5728375846731776.txt
created a situation in which
  cinfo->output_iMCU_row > cinfo->master->last_good_iMCU_row
but
  cinfo->input_scan_number == 1
thus causing decompress_smooth_data() to read from
prev_coef_bits_latch[], which was uninitialized.  I was unable to create
the same situation with a real JPEG image.
2020-11-28 07:06:08 -06:00
DRC
ccaba5d789 Fix buffer overrun with certain narrow prog JPEGs
Regression introduced by 6d91e950c8

last_block_column in decompress_smooth_data() can be 0 if, for instance,
decompressing a 4:4:4 image of width 8 or less or a 4:2:2 or 4:2:0 image
of width 16 or less.  Since last_block_column is an unsigned int,
subtracting 1 from it produced 0xFFFFFFFF, the test in line 590 passed,
and we attempted to access blocks from a second block column that didn't
actually exist.

Closes #476
2020-11-25 15:08:28 -06:00
DRC
cfc7e6e58e Bump revision to 2.0.91 for post-beta fixes 2020-11-25 14:10:55 -06:00
DRC
4e52b66f34 Travis: Use Docker tag that matches Git branch 2020-11-24 21:56:19 -06:00
DRC
8cf6f716bc Bump revision to 2.0.90 to prepare for beta 2020-11-24 21:32:48 -06:00
Jonathan Wright
eb14189caa Fix Neon SIMD build issues with Visual Studio
- Use the _M_ARM and _M_ARM64 macros provided by Visual Studio for
  compile-time detection of Arm builds, since __arm__ and __aarch64__
  are only present in GNU-compatible compilers.
- Neon/intrinsics: Use the _CountLeadingZeros() and
  _CountLeadingZeros64() intrinsics provided by Visual Studio, since
  __builtin_clz() and __builtin_clzl() are only present in
  GNU-compatible compilers.
- Neon/intrinsics: Since Visual Studio does not support static vector
  initialization, replace static initialization of Neon vectors with the
  appropriate intrinsics.  Compared to the static initialization
  approach, this produces identical assembly code with both GCC and
  Clang.
- Neon/intrinsics: Since Visual Studio does not support inline assembly
  code, provide alternative code paths for Visual Studio whenever inline
  assembly is used.
- Build: Set FLOATTEST appropriately for AArch64 Visual Studio builds
  (Visual Studio does not emit fused multiply-add [FMA] instructions by
  default for such builds.)
- Neon/intrinsics: Move temporary buffer allocation outside of nested
  loops.  Since Visual Studio configures Arm builds with a relatively
  small amount of stack memory, attempting to allocate those buffers
  within the inner loops caused a stack overflow.

Closes #461
Closes #475
2020-11-24 21:13:16 -06:00
DRC
91dd3b23ad ChangeLog: macOS Armv8/x86-64 univ. binary support 2020-11-24 20:31:59 -06:00
DRC
7e0d94d3a7 Merge branch 'master' into dev 2020-11-24 20:31:51 -06:00
DRC
1c839761cf Force Git to treat testorig.ppm as a binary file
Otherwise, because the file begins with an ASCII header, Git will
erroneously treat is as an ASCII file, and if Git for Windows is
configured with default options (specifically, "Checkout windows-style,
commit Unix-style line endings"), it will add carriage return characters
to all of the "linefeed" characters in the PPM file, thus corrupting it
and causing libjpeg-turbo's regression tests to fail.
2020-11-24 18:54:44 -06:00
DRC
6d91e950c8 Use 5x5 win & 9 AC coeffs when smoothing DC scans
... of progressive images.

Based on:
be8d36d13b
9d528f278e
85f36f0765
63a4d39e38
51336a6ad5

Closes #459
Closes #474
2020-11-24 18:21:42 -06:00
Kornel
1a7384c790 Run turbo's tests with turbo's settings
Fixes #384
2020-11-22 20:58:59 +00:00
Kornel
c302c77d17 Mark mozjpeg's output as acceptable 2020-11-22 20:58:59 +00:00
DRC
d523435e18 Travis: Use Xcode 12.2 for all iOS & macOS builds
There doesn't seem to be any performance or compatibility downside to
this, and it has the advantages of simplicity and consistency between
the PR and official builds.
2020-11-19 19:30:51 -06:00
Kornel
3940a92fa8 Readme refresh 2020-11-19 18:30:55 +00:00
DRC
1ac83cd636 Travis: The Mac build log is now log-macos.txt
(oversight from f7a10a61e3)
2020-11-18 18:16:12 -06:00
DRC
0ba70b6a13 Build: Support macOS Armv8/x86-64 univ. binaries
- Rename IOS_ARMV8_BUILD to ARMV8_BUILD.
- Rename install_ios() to install_subbuild() in makemacpkg.
- Wordsmith the build instructions accordingly.
- Use xcode12.2 image in Travis CI.
2020-11-18 17:40:44 -06:00
DRC
e417033d84 Merge branch 'master' into dev 2020-11-18 14:13:54 -06:00
DRC
6d2e8837b4 jpeg_skip_scanlines(): Avoid NULL + 0 UBSan error
This error occurs at the call to (*cinfo->cconvert->color_convert)() in
sep_upsample() whenever cinfo->upsample->need_context_rows == TRUE
(i.e. whenever h2v2 or h1v2 fancy upsampling is used.)  The error is
innocuous, since (*cinfo->cconvert->color_convert)() points to a dummy
function (noop_convert()) in that case.

Fixes #470
2020-11-18 13:33:47 -06:00
DRC
f7c5489244 Travis: Add /opt/local/bin to PATH for Mac build
(oversight from previous commit)

macports-ci does this, and it's necessary in order for the build script
to find md5sum.
2020-11-18 10:11:21 -06:00
DRC
f7a10a61e3 Build: "OS X"/"OSX" = "macOS"/"MACOS"
There are no supported versions of "OS X" anymore.  The operating system
has been named "macOS" since 10.12 Sierra, which was released four years
ago.
2020-11-17 13:53:33 -06:00
DRC
d111d9ff7a Merge branch 'master' into dev 2020-11-17 11:54:20 -06:00
DRC
10ba6ed336 Travis: Install MacPorts without using macports-ci 2020-11-16 17:38:06 -06:00
DRC
292d78e786 Merge branch 'master' into dev 2020-11-16 15:28:02 -06:00
DRC
88bf1d1678 Build: Set FLOATTEST more intelligently
The "32bit" vs. "64bit" floating point test results actually have
nothing to do with the FPU.  That was a fallacious assumption based on
the observation that, with multiple CPU types, 32-bit and 64-bit builds
produce different floating point test results.  It seems that this is,
in fact, due to differing compiler behavior-- more specifically, whether
fused multiply-add (FMA) instructions are used to combine multiple
floating point operations into a single instruction ("floating point
expression contraction".)  GCC does this by default if the target
supports FMA instructions, which PowerPC and AArch64 targets both do.

Fixes #468
2020-11-16 15:19:42 -06:00
DRC
8f8305981b Merge branch 'master' into dev 2020-11-13 15:21:26 -06:00
DRC
42f7c78fe3 BUILDING.md: Use min. iOS v8 in iOS Armv8 example
This is necessary in order to enable thread-local storage.
2020-11-13 15:18:35 -06:00
DRC
33859880e9 Neon: Auto-detect compiler intrinsics completeness
This allows the Neon intrinsics code to be built successfully (albeit
likely with reduced run-time performance) with Xcode 5.0-6.2
(iOS/AArch64) and Android NDK < r19 (AArch32).  Note that Xcode 5.0-6.2
will not build the Armv8 GAS code without gas-preprocessor.pl, and no
version of Xcode will build the Armv7 GAS code without
gas-preprocessor.pl, so we always use the full Neon intrinsics
implementation by default with macOS and iOS builds.

Auto-detecting the completeness of the compiler's set of Neon intrinsics
also allows us to more intelligently set the default value of
NEON_INTRINSICS, based on the values of HAVE_VLD1*.  This is a
reasonable, albeit imperfect, proxy for whether a compiler has a full
and optimal set of Neon intrinsics.  Specific notes:

  - 64-bit RGB-to-YCbCr color conversion
    does not use any of the intrinsics in question, regresses with GCC
  - 64-bit accurate integer forward DCT
    uses vld1_s16_x3(), regresses with GCC
  - 64-bit Huffman encoding
    uses vld1q_u8_x4(), regresses with GCC
  - 64-bit YCbCr-to-RGB color conversion
    does not use any of the intrinsics in question, regresses with GCC
  - 64-bit accurate integer inverse DCT
    uses vld1_s16_x3(), regresses with GCC
  - 64-bit 4x4 inverse DCT
    uses vld1_s16_x3().  I did not test this algorithm in isolation, so
    it may in fact regress with GCC, but the regression may be hidden by
    the speedup from the new SIMD-accelerated upsampling algorithms.

  - 32-bit RGB-to-YCbCr color conversion:
    uses vld1_u16_x2(), regresses with GCC
  - 32-bit accurate integer forward DCT
    uses vld1_s16_x3(), regression irrelevant because there was no
    previous implementation
  - 32-bit accurate integer inverse DCT
    uses vld1_s16_x3(), regresses with GCC
  - 32-bit fast integer inverse DCT
    does not use any of the intrinsics in question, regresses with GCC
  - 32-bit 4x4 inverse DCT
    uses vld1_s16_x3().  I did not test this algorithm in isolation, so
    it may in fact regress with GCC, but the regression may be hidden by
    the speedup from the new SIMD-accelerated upsampling algorithms.

Presumably when GCC includes a full and optimal set of Neon intrinsics,
the HAVE_VLD1* tests will pass, and the full Neon intrinsics
implementation will be enabled automatically.
2020-11-13 15:16:34 -06:00
DRC
3e9e7c7055 Fix build if WITH_12BIT==1 && WITH_JPEG(7|8)==1
Fixes #466
2020-11-11 17:54:06 -06:00
DRC
bbd8089297 Neon: Finalize intrinsics implementation
- Remove gas-preprocessor.pl.  None of the compilers that can build the
  new intrinsics implementation require gas-preprocessor.pl (tested
  with Xcode and with Clang 3.9+ for Linux.)
- Document that Xcode 6.3.x or later is now required for iOS builds
  (older versions of Xcode do not have a full set of Neon intrinsics.)
- Add a change log entry.
- Do not enable the ASM CMake language unless NEON_INTRINSICS is false.
- Add a Clang/Arm64 test to .travis.yml in order to test the new
  intrinsics implementation.

Closes #455
2020-11-10 19:58:28 -06:00
Martyn Jacques
141f26ff6d Neon: Intrinsics impl. of 2x2 and 4x4 scaled IDCTs
The previous AArch32 and AArch64 GAS implementations have been removed,
since the intrinsics implementations provide the same or better
performance.
2020-11-10 19:09:09 -06:00
Jonathan Wright
4574f01f43 Neon: Intrinsics impl. of h2v1 & h2v2 plain upsamp
There was no previous GAS implementation.

NOTE: This doesn't produce much of a speedup when using -O3, because -O3
already enables Neon autovectorization, which works well for the scalar
C implementation of plain upsampling.  However, the Neon SIMD
implementation will benefit other optimization levels.
2020-11-10 19:09:09 -06:00
Jonathan Wright
ba52a3de32 Neon: Intrinsics impl of h2v1 & h2v2 merged upsamp
There was no previous GAS implementation.

This commit also reverts 40557b2301 and
7723d7f7d0.
7723d7f7d0 was only necessary because
there was no Neon implementation of merged upsampling/color conversion,
and 40557b2301 was only necessary because
of 7723d7f7d0.
2020-11-10 19:09:09 -06:00
Jonathan Wright
240ba417aa Neon: Intrinsics impl. of prog. Huffman encoding
The previous AArch64 GAS implementation has been removed, since the
intrinsics implementation provides the same or better performance.
There was no previous AArch32 GAS implementation.
2020-11-10 19:09:09 -06:00
Jonathan Wright
ed581cd935 Neon: Intrinsics impl. of accurate int inverse DCT
The previous AArch32 and AArch64 GAS implementations are retained by
default when using GCC, in order to avoid a performance regression.  The
intrinsics implementation can be forced on or off using the new
NEON_INTRINSICS CMake variable.
2020-11-10 19:09:09 -06:00
Jonathan Wright
2c6b68e283 Neon: Intrinsics impl. of fast integer Inverse DCT
The previous AArch32 GAS implementation is retained by default when
using GCC, in order to avoid a performance regression.  The intrinsics
implementation can be forced on or off using the new NEON_INTRINSICS
CMake variable.  The previous AArch64 GAS implementation has been
removed, since the intrinsics implementation provides the same or better
performance.
2020-11-10 19:09:09 -06:00
Jonathan Wright
2acfb93c94 Neon: Intrinsics impl. of h1v2 fancy upsamling
There was no previous GAS implementation.
2020-11-10 19:09:09 -06:00
Jonathan Wright
975307775c Neon: Intrinsics impl. of h2v1 & h2v2 fancy upsamp
The previous AArch32 GAS implementation of h2v1 fancy upsampling has
been removed, since the intrinsics implementation provides the same or
better performance.  There was no previous GAS implementation of h2v2
fancy upsampling, and there was no previous AArch64 GAS implementation
of h2v1 fancy upsampling.
2020-11-10 19:09:09 -06:00
Jonathan Wright
5dbd39323c Neon: Intrinsics implementation of YCbCr->RGB565
The previous AArch64 GAS implementation is retained by default when
using GCC, in order to avoid a performance regression.  The intrinsics
implementation can be forced on or off using the new NEON_INTRINSICS
CMake variable.  The previous AArch32 GAS implementation has been
removed, since the intrinsics implementation provides the same or better
performance.
2020-11-10 19:09:09 -06:00
Jonathan Wright
0f35cd68f2 Neon: Intrinsics implementation of YCbCr->RGB
The previous AArch64 GAS implementation is retained by default when
using GCC, in order to avoid a performance regression.  The intrinsics
implementation can be forced on or off using the new NEON_INTRINSICS
CMake variable.  The previous AArch32 GAS implementation has been
removed, since the intrinsics implementation provides the same or better
performance.
2020-11-10 19:09:09 -06:00
Jonathan Wright
f3c3f01d23 Neon: Intrinsics impl. of Huffman encoding
The previous AArch64 GAS implementation is retained by default when
using GCC, in order to avoid a performance regression.  The intrinsics
implementation can be forced on or off using the new NEON_INTRINSICS
CMake variable.  The previous AArch32 GAS implementation has been
removed, since the intrinsics implementation provides the same or better
performance.
2020-11-10 19:09:09 -06:00
Jonathan Wright
d0004de5dd Neon: Intrinsics impl. of accurate int forward DCT
The previous AArch64 GAS implementation is retained by default when
using GCC, in order to avoid a performance regression.  The intrinsics
implementation can be forced on or off using the new NEON_INTRINSICS
CMake variable.  There was no previous AArch32 GAS implementation.
2020-11-10 19:09:09 -06:00
Jonathan Wright
3d84668d42 Neon: Intrinsics impl. of fast integer forward DCT
The previous AArch32 and AArch64 GAS implementations have been removed,
since the intrinsics implementation provides the same or better
performance.
2020-11-10 19:09:09 -06:00
Jonathan Wright
951d3677eb Neon: Intrinsics impl. of int sample conv./quant.
The previous AArch32 and AArch64 GAS implementations have been removed,
since the intrinsics implementation provides the same or better
performance.
2020-11-10 19:09:09 -06:00
Jonathan Wright
366168aa7d Neon: Intrinsics impl. of h2v1 & h2v2 downsampling
The previous AArch64 GAS implementation has been removed, since the
intrinsics implementation provides the same or better performance.
There was no previous AArch32 GAS implementation.
2020-11-10 19:09:09 -06:00
Jonathan Wright
f73b1dbc60 Neon: Intrinsics implementation of RGB->Grayscale
There was no previous GAS implementation.
2020-11-10 19:09:09 -06:00
Jonathan Wright
4f2216b435 Neon: Intrinsics implementation of RGB->YCbCr
The previous AArch32 and AArch64 GAS implementations are retained by
default when using GCC, in order to avoid a performance regression.  The
intrinsics implementation can be forced on or off using a new
NEON_INTRINSICS CMake variable.
2020-11-10 19:09:05 -06:00
DRC
0efc4858d4 Merge branch 'master' into dev 2020-11-09 19:02:28 -06:00
DRC
02227e48a9 Travis: Combine PPC/Arm tests with jpeg-7/8 tests
There is no reason not to, since the jpeg-7 and jpeg-8 API/ABI tests do
not exercise the SIMD extensions any differently than the other tests.
2020-11-09 18:20:41 -06:00
DRC
c7dd191271 Merge branch 'master' into dev 2020-11-08 15:15:02 -06:00
DRC
40557b2301 Build: Fix test failures w/ Arm Neon SIMD exts
Regression caused by
a46c111d9f

Because of 7723d7f7d0, which was
introduced in libjpeg-turbo 1.5.1 in response to #81, merged upsampling/
color conversion is disabled on platforms that have SIMD-accelerated
YCbCr -> RGB color conversion but not SIMD-accelerated merged
upsampling/color conversion.  This was intended to improve performance
with the Neon SIMD extensions, since those are the only SIMD extensions
for which those circumstances apply.  Under normal circumstances, the
separate "plain" (non-fancy) upsampling and color conversion routines
will produce bitwise-identical output to the merged upsampling/color
conversion routines, but that is not the case when skipping scanlines
starting at an odd-numbered scanline.  The modified test introduced in
a46c111d9f does precisely that in order to
validate the fixes introduced in
9120a24743 and
a46c111d9f.

Because of 7723d7f7d0, the segfault fixed
in 9120a24743 and
a46c111d9f didn't affect the Neon SIMD
extensions, so this commit effectively reverts the test modifications in
a46c111d9f when using those SIMD
extensions.  We can get rid of this hack, as well as
7723d7f7d0, once a Neon implementation of
merged upsampling/color conversion is available.
2020-11-08 14:57:01 -06:00
DRC
a524b9b06b Travis: Regression-test Armv8 and PPC SIMD exts
Currently this only tests the 64-bit code paths, but it's better than
nothing.
2020-11-06 17:24:16 -06:00
DRC
7c1a1789d2 Merge branch 'master' into dev 2020-11-05 16:04:55 -06:00
DRC
6e632af9f6 Demote "fast" [I]DCT algorithms to legacy status
- Refer to the "slow" [I]DCT algorithms as "accurate" instead, since
  they are not slow under libjpeg-turbo.
- Adjust documentation claims to reflect the fact that the "slow" and
  "fast" algorithms produce about the same performance on AVX2-equipped
  CPUs (because of the dual-lane nature of AVX2, it was not possible to
  accelerate the "fast" algorithm beyond what was achievable with SSE2.)
  Also adjust the claims to reflect the fact that the "fast" algorithm
  tends to be ~5-15% faster than the "slow" algorithm on
  non-AVX2-equipped CPUs, regardless of the use of the libjpeg-turbo
  SIMD extensions.
- Indicate the legacy status of the "fast" and float algorithms in the
  documentation and cjpeg/djpeg usage info.
- Remove obsolete paragraph in the djpeg man page that suggested that
  the float algorithm could be faster than the "fast" algorithm on some
  CPUs.
2020-11-05 15:59:31 -06:00
DRC
cd342acf7f Merge branch 'master' into dev 2020-10-27 16:45:23 -05:00
DRC
c3bfbde21d jpegtran.c: "subarea" = "region"
It is our convention to use the term "region" when referring to crop
specs, since this is more consistent with the terminology used by the
rest of the image processing community.
2020-10-27 15:45:24 -05:00
DRC
a8656d703d jpegtran.1: Minor formatting tweak 2020-10-27 15:45:24 -05:00
DRC
9ecb67c219 transupp.c: Code formatting tweaks 2020-10-27 15:45:24 -05:00
DRC
53c685b7f4 cdjpeg.h: Remove unused function stub
enable_signal_catcher() was only needed with libjpeg's temp. file memory
manager (jmemname.c), which libjpeg-turbo has never supported.
2020-10-27 15:45:24 -05:00
DRC
d27b935a88 Consistify formatting to simplify checkstyle
The checkstyle script was hastily developed prior to libjpeg-turbo 2.0
beta1, so it has a lot of exceptions and is thus prone to false
negatives.  This commit eliminates some of those exceptions.
2020-10-27 15:45:09 -05:00
DRC
88ae60986e Merge branch 'ijg' into dev
- Restore GIF read/compressed GIF write support from jpeg-6a and
  jpeg-9d.
- Integrate jpegtran -wipe and -drop options from jpeg-9a and jpeg-9d.
- Integrate jpegtran -crop extension (for expanding the image size) from
  jpeg-9a and jpeg-9d.
- Integrate other minor code tweaks from jpeg-9*
2020-10-27 13:32:13 -05:00
DRC
7e4eac7021 Merge branch 'master' into dev 2020-10-26 09:41:32 -05:00
Guido Vollbeding
9fc018fd1a The Independent JPEG Group's JPEG software v9d 2020-10-23 10:00:48 -05:00
Guido Vollbeding
96e4e7eb60 The Independent JPEG Group's JPEG software v9c 2020-10-23 09:56:39 -05:00
DRC
26e3aedbe5 README.ijg: Update URLs; remove Usenet info 2020-10-22 23:06:22 -05:00
DRC
b4525f9f16 jversion.h: Update copyrights 2020-10-19 22:05:09 -05:00
DRC
59352195b2 Merge branch 'master' into dev 2020-10-19 21:17:46 -05:00
DRC
f7ca3c5a3d Build: Improve Arm 32-bit cross-comp./packaging
- Set CPU_TYPE=arm if performing a 32-bit build on an AArch64 system.
  This eliminates the need to use a CMake toolchain file.
- Set RPMARCH=armv7hl if building on a 32-bit Arm system with an FPU.
- Set RPMARCH=armv7hl and DEBARCH=armhf if performing a 32-bit build
  using a gnueabihf toolchain.
- If performing a 32-bit Arm build, generate a 32-bit supplementary DEB
  package for AArch64 systems.
2020-10-19 16:25:11 -05:00
DRC
1ed312eab6 "ARM"="Arm", "NEON"="Neon"
Refer to:
https://www.arm.com/company/policies/trademarks/arm-trademark-list/arm-trademark
https://www.arm.com/company/policies/trademarks/arm-trademark-list/neon-trademark

NOTE: These changes are only applied to change log entries for 2.0.x and
later, since the change log is a historical record and Arm's new
trademark policy did not go into effect until late 2017.
2020-10-15 17:47:31 -05:00
DRC
b8200c6601 Build: Add CMake package config files
Based on:
d34b89b411

Closes #339
Closes #342
2020-10-15 10:26:54 -05:00
DRC
ea8f643c16 Build: Remove lib32 symlink from official Mac pkg
(oversight from 4c5a15c362)
2020-10-15 10:26:17 -05:00
DRC
460dfe40e1 ChangeLog: Acknowledge 2.0.6 release 2020-10-15 10:26:17 -05:00
DRC
ae08115d4d Merge branch 'master' into dev 2020-10-15 10:25:46 -05:00
DRC
b5a1472781 Build: Fix permissions 2020-10-15 10:22:51 -05:00
DRC
190382b75f ChangeLog: Fix minor formatting issue 2020-10-14 15:14:26 -05:00
DRC
8789a5e255 Merge branch 'master' into dev 2020-10-01 21:27:47 -05:00
DRC
89c88c2509 ChangeLog.md: jpeg_crop_scanline(), not scanlines 2020-10-01 21:26:04 -05:00
DRC
2ec4a5ebe3 Fix dec artifacts w/cropped+smoothed prog DC scans
This commit modifies decompress_smooth_data(), adding missing MCU column
offsets to the prev_block_row and next_block_row indices that are used
for block rows other than the first and last.  Effectively, this
eliminates unexpected visual artifacts when using jpeg_crop_scanline()
along with interblock smoothing while decompressing the DC scan of a
progressive JPEG image.

Based on:
0227d4fb48

Fixes #456
Closes #457
2020-10-01 21:22:58 -05:00
DRC
1d7faf84a0 Merge branch 'master' into dev 2020-10-01 18:17:46 -05:00
DRC
8e895c79e1 Java dox: Fix errors w/ javadoc in Java 8 or later 2020-10-01 18:14:21 -05:00
DRC
2b121d39e7 Merge branch 'master' into dev 2020-10-01 16:20:14 -05:00
DRC
2d14fc2e3b Dox: Re-generate using Doxygen 1.8.20
This fixes a GitHub Dependabot alert regarding jquery.js.

Fixes #421
2020-10-01 14:36:30 -05:00
Kornel
d23e3fc586 Update release token 2020-09-29 11:41:33 +01:00
Kornel Lesiński
f1d512de2f Make test output match turbojpeg tests 2020-09-29 11:41:14 +01:00
dofuuz
751ce7d9f3 Automate Windows build and deploy (with PNG support) (#379) 2020-09-29 11:40:16 +01:00
Kornel
ffea183e55 Response to the rumor mill 2020-09-29 10:32:19 +01:00
dofuuz
3fed7e016b Add PNG support to cjpeg shared build 2020-09-20 23:11:41 +01:00
DRC
6ab61fa1d1 Merge branch 'master' into dev 2020-09-13 17:02:27 -05:00
DRC
fe5b6a1c7c TJPEG: Remove unnecessary setCompDefaults() retval
setCompDefaults() hasn't thrown an error since
aa7459050d was introduced in 2.0.x.
2020-09-13 16:58:08 -05:00
Kornel Lesiński
8fb32c0a39 Work around fussy zlib on macOS 2020-08-15 19:36:42 +01:00
Kornel Lesiński
b3e739028a Merge libjpeg-turbo 2.0.5
* tag '2.0.5':
  TurboJPEG: Make global error handling thread-safe
  ChangeLog.md: Add missing sub-header for 2.0.5
  ChangeLog.md: List CVE ID fixed by previous commit
  rdppm.c: Fix buf overrun caused by bad binary PPM
  Build: Add missing jpegtran-icc test dependency
  rdswitch.c: Eliminate spaces before semicolons
  TJCompressor.compress(int): Fix YUV-to-JPEG error
  Bump version to 2.0.5; Document previous commit
  MIPS DSPr2: Work around various 'make test' errors
  MIPS DSPr2: Fix compiler warning with -mdspr2
  MIPS SIMD: Always honor JSIMD_FORCE* env vars
  Test: Honor CMAKE_CROSSCOMPILING_EMULATOR variable
2020-08-15 19:36:31 +01:00
DRC
6ee5d5f568 ARMv8 NEON: Support Windows builds w/AArch64 MinGW
Based on:
c5ef665928

Closes #438
2020-07-28 18:24:41 -05:00
DRC
fe79f56b77 Merge branch 'master' into dev 2020-07-28 15:09:00 -05:00
DRC
c1037f4380 Fix bad return val when skipping past end of image
Fixes #439
2020-07-28 14:59:41 -05:00
DRC
30282a878c README.md, jquant2.c: Use gender-neutral pronouns
Closes #444
2020-07-28 13:08:35 -05:00
DRC
a46c111d9f Further jpeg_skip_scanlines() fixes
- Introduce a partial image decompression regression test script that
  validates the correctness of jpeg_skip_scanlines() and
  jpeg_crop_scanlines() for a variety of cropping regions and libjpeg
  settings.

  This regression test catches the following issues:
  #182, fixed in 5bc43c7821
  #237, fixed in 6e95c08649794f5018608f37250026a45ead2db8
  #244, fixed in 398c1e9acc
  #441, fully fixed in this commit

  It does not catch the following issues:
  #194, fixed in 773040f9d9
  #244 (additional segfault), fixed in
       9120a24743

- Modify the libjpeg-turbo regression test suite (make test) so that it
  checks for the issue reported in #441 (segfault in
  jpeg_skip_scanlines() when used with 4:2:0 merged upsampling/color
  conversion.)

- Fix issues in jpeg_skip_scanlines() that caused incorrect output with
  h2v2 (4:2:0) merged upsampling/color conversion.  The previous commit
  fixed the segfault reported in #441, but that was a symptom of a
  larger problem.  Because merged 4:2:0 upsampling uses a "spare row"
  buffer, it is necessary to allow the upsampler to run when skipping
  rows (fancy 4:2:0 upsampling, which uses context rows, also requires
  this.)  Otherwise, if skipping starts at an odd-numbered row, the
  output image will be incorrect.

- Throw an error if jpeg_skip_scanlines() is called with two-pass color
  quantization enabled.  With two-pass color quantization, the first
  pass occurs within jpeg_start_decompress(), so subsequent calls to
  jpeg_skip_scanlines() interfere with the multipass state and prevent
  the second pass from occurring during subsequent calls to
  jpeg_read_scanlines().
2020-07-28 12:47:53 -05:00
DRC
9120a24743 Fix jpeg_skip_scanlines() segfault w/merged upsamp
The additional segfault mentioned in #244 was due to the fact that
the merged upsamplers use a different private structure than the
non-merged upsamplers.  jpeg_skip_scanlines() was assuming the latter, so
when merged upsampling was enabled, jpeg_skip_scanlines() clobbered one
of the IDCT method pointers in the merged upsampler's private structure.

For reasons unknown, the test image in #441 did not encounter this
segfault (too small?), but it encountered an issue similar to the one
fixed in 5bc43c7821, whereby it was
necessary to set up a dummy postprocessing function in
read_and_discard_scanlines() when merged upsampling was enabled.
Failing to do so caused either a segfault in merged_2v_upsample() (due
to a NULL pointer being passed to jcopy_sample_rows()) or an error
("Corrupt JPEG data: premature end of data segment"), depending on the
number of scanlines skipped and whether the first scanline skipped was
an odd- or even-numbered row.

Fixes #441
Fixes #244 (for real this time)
2020-07-23 23:19:13 -05:00
DRC
c965dc7a79 ChangeLog.md: Add missing sub-header for 2.0.6 2020-07-22 13:59:27 -05:00
DRC
b9142b21f8 Android: Fix "using JNI after critical get" errors
(again.)

Fixes #300
2020-07-22 13:53:21 -05:00
DRC
7d829bfa30 Bump version to 2.0.6 to prepare for new commits 2020-07-07 10:16:29 -05:00
DRC
fb6f5e8b01 Java/Mac:Remove obsolete libturbojpeg.jnilib alias
IIRC, this was only necessary with the version of Java 1.5 that shipped
with OS X 10.4 "Tiger".  Apple's implementation of Java 6 ("Java for
OS X Systems") supported both .jnilib and .dylib extensions for JNI
libraries, but Oracle's implementation of Java has only ever supported
the .dylib extension.
2020-06-25 21:41:30 -05:00
DRC
c77783ed41 BUILDING.md: Undocument 32-bit Mac build/packaging
(oversight from previous commit)
2020-06-25 21:28:33 -05:00
DRC
4c5a15c362 Eliminate 32-bit Mac build/packaging support
The scales have now tilted overwhelmingly in favor of eliminating
support for 32-bit Macs:

- 32-bit applications are only necessary in order to support OS X 10.5
  "Leopard" and OS X 10.6 "Snow Leopard".  OS X 10.7 "Lion" requires a
  64-bit Mac and supports all 64-bit Macs.
- 32-bit applications are no longer allowed in the macOS App Store.
- 32-bit applications no longer run in macOS 10.15 "Catalina".
- 32-bit applications do not support thread-local storage, so the
  TurboJPEG API library's global error handler is not thread-safe with
  such applications.
- libjpeg-turbo 2.1.x no longer supports 32-bit iOS apps, so it makes
  sense to also eliminate support for 32-bit macOS applications.

It's time.
2020-06-25 19:48:18 -05:00
DRC
b797f70012 Build: Eliminate Cygwin packaging support
We haven't provided official Cygwin builds since 1.4.x, since Cygwin
now supplies its own libjpeg-turbo packages (although they apparently
haven't been updated past 1.5.3.)
2020-06-25 19:05:45 -05:00
DRC
80d77720c3 AppVeyor: We no longer build/package JNI JARs
This was done solely to support Java Web Start, which is now obsolete.
2020-06-19 00:22:49 -05:00
DRC
aecee25695 Merge branch 'master' into dev 2020-06-19 00:03:51 -05:00
DRC
ae87a95861 TurboJPEG: Make global error handling thread-safe
... on platforms that support thread-local storage.  This currently
includes all supported platforms except 32-bit macOS.

Fixes #396
2020-06-18 23:40:20 -05:00
DRC
b443c541b9 ChangeLog.md: Add missing sub-header for 2.0.5 2020-06-03 16:08:08 -05:00
DRC
cf483eee49 ChangeLog.md: List CVE ID fixed by previous commit 2020-06-03 16:04:06 -05:00
DRC
70040cb7ee Merge branch 'master' into dev 2020-06-02 15:05:43 -05:00
DRC
3de15e0c34 rdppm.c: Fix buf overrun caused by bad binary PPM
This extends the fix in 1e81b0c3ea to
include binary PPM files with maximum values < 255, thus preventing a
malformed binary PPM input file with those specifications from
triggering an overrun of the rescale array and potentially crashing
cjpeg, TJBench, or any program that uses the tjLoadImage() function.

Fixes #433
2020-06-02 14:51:17 -05:00
Andrew Childs
a2291b252d Build: Add missing jpegtran-icc test dependency
The jpegtran-icc test must run after the cjpeg-rgb-islow test, since
the latter generates testout_rgb_islow.jpg.
2020-05-05 00:38:39 -05:00
DRC
219e8e8f65 Merge branch 'master' into dev 2020-04-02 22:26:19 -05:00
DRC
a36deef563 rdswitch.c: Eliminate spaces before semicolons
(detected with a modified version of checkstyle)
2020-04-02 22:25:44 -05:00
Chan, Danny
6d95c51adf Fix markdown format 2020-03-11 14:31:37 +00:00
DRC
b0f92a1d6c Merge branch 'master' into dev 2020-03-04 11:09:41 -06:00
NancyLi1013
5ea5482872 Add vcpkg installation instructions (#353)
* Add vcpkg installation instructions
2020-02-26 10:51:25 +00:00
DRC
8cc1277b69 TJCompressor.compress(int): Fix YUV-to-JPEG error
Due to an oversight, the TJCompressor.compress(int) method did not
handle YUV source images.

Fixes #413
2020-02-24 13:35:30 -06:00
DRC
77ff3bd66d Merge branch 'master' into dev 2020-02-18 12:56:01 -06:00
DRC
ecf5f9a96a Bump version to 2.0.5; Document previous commit 2020-02-18 10:43:48 -06:00
DRC
00d48d7e8c Merge branch 'master' into dev 2020-02-17 18:14:10 -06:00
DRC
035262a18d MIPS DSPr2: Work around various 'make test' errors
Referring to #408, this commit #ifdefs DSPr2 SIMD functions that only
work on little endian processors, and it completely excludes
jsimd_h2v1_downsample_dspr2() and jsimd_h2v2_downsample_dspr2().  The
latter two functions fail with the TJBench tiling regression tests, most
likely because the implementation of the functions predates those tests.
2020-02-17 18:13:31 -06:00
DRC
ed7cab47d9 MIPS DSPr2: Fix compiler warning with -mdspr2
If -mdspr2 is passed to the compiler, __mips_dsp will be defined, and
__mips_dsp_rev will be >= 2, so parse_proc_cpuinfo() will not be used.
2020-02-17 16:35:00 -06:00
DRC
42d679b9fc MIPS SIMD: Always honor JSIMD_FORCE* env vars
Previously, these environment variables were not honored unless a 74K
CPU was detected, but this detection doesn't work properly with QEMU's
user mode emulation.  With all other CPU types, libjpeg-turbo honors
JSIMD_FORCE* regardless of CPU detection.
2020-02-17 15:19:32 -06:00
DRC
044c22e12f Test: Honor CMAKE_CROSSCOMPILING_EMULATOR variable
This CMake variable is intended to define a wrapper program for
executing cross-compiled executables.  However, CTest doesn't use
CMAKE_CROSSCOMPILING_EMULATOR, because it isn't obvious which tests
should be executed with the wrapper and which tests are scripts that
don't need it.  This commit manually prepends
${CMAKE_CROSSCOMPILING_EMULATOR} to all unit test command lines that
execute a program built by the libjpeg-turbo build system.  Thus, one
can set CMAKE_CROSSCOMPILING_EMULATOR in a CMake toolchain file to (for
instance) "qemu-{architecture} {qemu_arguments}") in order to execute
all eligible unit tests using QEMU.
2020-02-17 14:41:43 -06:00
Kornel Lesiński
1d2320994d Merge remote-tracking branch 'turbo/master'
* turbo/master: (105 commits)
  makemacpkg.in: Allow universal DMG w/o ARMv8 arch
  Remove more unnecessary NULL checks before free()
  Eliminate unnecessary NULL checks before tjFree()
  Eliminate unnecessary NULL checks before free()
  simd/arm64/jsimd_neon.S: Fix checkstyle issue
  tjTransform(): Use instance err. for bad crop spec
  README.md, package specs: Various tweaks
  djpeg.c: Fix compiler warning w/o mem. src manager
  ARMv8 SIMD: Support execute-only memory (XOM)
  Travis: Use MacPorts instead of Homebrew
  Huffman enc.: Fix very rare local buffer overrun
  TurboJPEG: Fix erroneous subsampling detection
  ChangeLog.md: List CVE IDs for specific fixes
  tjDecompressToYUV*(): Fix OOB write/double free
  64-bit tjbench: Fix signed int overflow/segfault
  Fix copyright header formatting buglets
  example.txt: Avoid undefined setjmp() behavior
  Mac: Support hiding SIMD fct symbols w/ NASM 2.14+
  TJBench: Fix output with -componly -quiet
  Build: Don't require ASM_NASM if !REQUIRE_SIMD
  ...
2020-02-13 10:45:55 +00:00
DRC
9a2cf32317 Build: Enable separate iOS pkg/DMG w/ sim support
Refer to #406
2020-02-11 13:56:12 -06:00
DRC
6aabca86d3 Merge branch 'master' into dev 2020-02-11 12:47:12 -06:00
DRC
70327296e2 makemacpkg.in: Allow universal DMG w/o ARMv8 arch
(buglet)
2020-02-07 17:04:30 -06:00
DRC
379edfd815 AppVeyor: Use Visual C++ 2015 instead of 2010
Visual C++ < 2015 is no longer under mainstream support, and Visual C++
2010 will not be supported at all after July of this year.
(https://docs.microsoft.com/en-us/visualstudio/releases/2019/servicing)
2020-01-16 20:55:42 -06:00
DRC
ada6ea5105 BUILDING.md: Update Visual C++ recommendations 2020-01-16 20:52:15 -06:00
DRC
167b5a8059 Merge branch 'master' into dev 2020-01-08 15:02:58 -06:00
DRC
f81833aed6 Remove more unnecessary NULL checks before free() 2020-01-08 15:01:38 -06:00
DRC
4c57ad476c Merge branch 'master' into dev 2020-01-08 14:26:02 -06:00
DRC
00607ec260 Eliminate unnecessary NULL checks before tjFree()
+ document that tjFree() accepts NULL pointers without complaint.
Effectively, it has had that behavior all along, but the API does not
guarantee that tjFree() will be implemented with free() behind the
scenes, so it's best to formalize the behavior.
2020-01-08 14:24:37 -06:00
DRC
04d3143a65 Merge branch 'master' into dev 2020-01-07 16:21:03 -06:00
DRC
fdf8903354 Eliminate unnecessary NULL checks before free()
This programming practice (which exists in other code bases as well)
is a by-product of having used early C compilers that did not properly
handle free(NULL).  All modern compilers should properly handle that.

Fixes #398
2020-01-07 16:15:23 -06:00
DRC
b34c85ea4a Merge branch 'master' into dev 2019-12-31 01:20:12 -06:00
DRC
166e34213e simd/arm64/jsimd_neon.S: Fix checkstyle issue 2019-12-31 01:10:30 -06:00
DRC
c4675d62e8 Merge branch 'master' into dev 2019-12-31 00:58:42 -06:00
DRC
6367924ac6 tjTransform(): Use instance err. for bad crop spec
Addresses a concern raised in #396
2019-12-31 00:35:08 -06:00
DRC
29f718ee63 README.md, package specs: Various tweaks
- Don't enumerate the types of SIMD instructions that libjpeg-turbo
  supports, as this can change without notice.
- Use more clear terminology when describing support for libjpeg v7/v8
  features ("libjpeg" is, colloquially but not officially, the name for
  the IJG's software, whereas the "libjpeg API" refers to our emulation
  of said software.)
- "PhotoShop" = "Photoshop" (StudLy Caps Police)
- Adjust dynamic library versions to reflect the addition of
  jpeg_read_icc_profile() and jpeg_write_icc_profile() in
  libjpeg-turbo 2.0.x.
2019-12-31 00:27:04 -06:00
DRC
fe50cd9978 djpeg.c: Fix compiler warning w/o mem. src manager
insize is only used when the in-memory source manager is compiled in.
2019-12-31 00:05:05 -06:00
DRC
b542e4c8e9 ARMv8 SIMD: Support execute-only memory (XOM)
Move constants out of the .text section in simd/arm64/jsimd_neon.S and
into a .rodata section.  This ensures that the ARMv8 NEON SIMD
extensions are compatible with memory layouts that are marked
execute-only (and thus unreadable.)

Based on:
88f3ca7664

Closes #318
2019-12-20 14:24:10 -06:00
DRC
80acd5c4a7 Remove code for the obsolete RLE image format
libjpeg-turbo never included that code, because it requires an external
library (the Utah Raster Toolkit.)  The RLE image format was supplanted
by GIF in the late 1980s, so it is rarely seen these days.  (It had a
lousy Weissman score, anyhow.)
2019-12-19 10:36:26 -06:00
DRC
5000eaa3a6 cdjpeg.c: Fix Visual C++ compiler warning
(introduced by previous commit)
2019-12-19 10:13:05 -06:00
DRC
e98b061282 Add fault tolerance features to djpeg and jpegtran
- Enable progress reporting at run time using a new -report argument
  (cjpeg now supports that argument as well)
- Limit the allowable number of scans using a new -maxscans argument
- Treat warnings as fatal using a new -strict argument

This mainly demonstrates how to work around the two issues with the
JPEG standard described here:
https://libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf
since those and similar issues continue to be erroneously reported as
libjpeg-turbo bugs.
2019-12-18 15:35:56 -06:00
DRC
54288598bb ChangeLog.md: Document 81b8c0ee 2019-12-17 15:48:10 -06:00
DRC
81b8c0eed5 Loongson MMI: Merge with MIPS64/add auto-detection
Modern Loongson processors are MIPS64-compatible, and MMI instructions
are now supported in the mainline of GCC.  Thus, this commit adds
compile-time and run-time auto-detection of MMI instructions and moves
the MMI SIMD extensions for libjpeg-turbo from simd/loongson/ to
simd/mips64/.  That will allow MMI and MSA instructions to co-exist
in the same build once #377 has been integrated.

Based on:
82953ddd61

Closes #383
2019-12-17 14:35:49 -06:00
DRC
52fef34928 Eliminate internal use of GETJOCTET() macro
Because of 01e3032354 (officially
eliminating support for compilers without unsigned char, since we never
effectively supported those compilers anyhow), GETJOCTET() is now a
no-op.  Since that macro is in jmorecfg.h, it is part of the de facto
libjpeg API and must remain in the public headers.  However, there is no
reason to continue using it internally, and eliminating its internal use
improves code readability.
2019-12-10 19:10:55 -06:00
mayeut
e821464f79 ARM64 NEON SIMD impl. of prog. Huffman encoding
This commit adds ARM64 NEON optimizations for the
encode_mcu_AC_first() and encode_mcu_AC_refine() functions used in
progressive Huffman encoding.

Compression speedups for the typical set of five libjpeg-turbo test
images (https://libjpeg-turbo.org/About/Performance):
Cortex-A53: 23.8-39.2% (avg. 32.2%)
Cortex-A72: 26.8-41.1% (avg. 33.5%)
Apple A7:  29.7-45.9% (avg. 39.6%)

Closes #229
2019-12-10 00:21:57 -06:00
DRC
b8a7680e12 Merge branch 'master' into dev 2019-12-05 22:38:05 -06:00
DRC
52291467e1 Travis: Use MacPorts instead of Homebrew
Homebrew tends to drop support for a macOS release the second that Apple
stops releasing security updates for it, and that makes HB difficult to
use with some of the Travis macOS images.  Furthermore, even on
supported macOS releases, HB sometimes tries to build GCC from source
even if a binary (bottle) is available.  Long story short, MacPorts just
generally has better backward compatibility.  MacPorts is also what I
personally use on the official libjpeg-turbo build machine.
2019-12-05 22:28:18 -06:00
DRC
f64c5508df Merge branch 'master' into dev 2019-12-05 15:41:28 -06:00
DRC
c76f4a0826 Huffman enc.: Fix very rare local buffer overrun
... detected by ASan.  This is a similar issue to the issue that was
fixed with 402a715f82.  Apparently it is
possible to create a malformed JPEG image that exceeds the Huffman
encoder's 256-byte local buffer when attempting to losslessly tranform
the image.  That makes sense, given that it was necessary to extend the
Huffman decoder's local buffer to 512 bytes in order to handle all
pathological cases (refer to 0463f7c9aad060fcd56e98d025ce16185279e2bc.)

Since this issue affected only lossless transformation, a workflow that
isn't generally exposed to arbitrary data exploits, and since the
overrun did not overflow the stack (i.e. it did not result in a segfault
or other user-visible issue, and valgrind didn't even detect it), it did
not likely pose a security risk.

Fixes #392
2019-12-05 14:47:05 -06:00
DRC
26b4d62a65 Merge branch 'master' into dev 2019-11-15 13:58:22 -06:00
DRC
c0b16e3d2b TurboJPEG: Fix erroneous subsampling detection
... that caused some JPEG images with unusual sampling factors to be
misidentified as 4:4:4.  This led to a buffer overflow when attempting
to decompress some such images using tjDecompressToYUV*().

Regression introduced by 479501b07c

The correct behavior is for the TurboJPEG API to refuse to decompress
such images, which it did prior to the aforementioned commit.

Fixes #389
2019-11-15 13:48:50 -06:00
DRC
6cedf37c83 ChangeLog.md: List CVE IDs for specific fixes 2019-11-15 12:46:49 -06:00
DRC
9c6f79e919 Fix formatting issues detected by checkstyle 2019-11-14 12:16:38 -06:00
DRC
f60b6dd36f Remove vestigial jpeg_nbits_table.inc
Not needed since 087c29e07f
2019-11-12 17:42:39 -06:00
DRC
c43a5081ce Merge branch 'master' into dev 2019-11-12 17:07:46 -06:00
DRC
bd20344b0a tjDecompressToYUV*(): Fix OOB write/double free
... when attempting to decompress grayscale JPEG images with sampling
factors != 1.

Fixes #387
2019-11-12 16:35:57 -06:00
DRC
c30b1e72da 64-bit tjbench: Fix signed int overflow/segfault
... that occurred when attempting to decompress images with more than
715827882 (2048*1024*1024 / 3) pixels.

Fixes #388
2019-11-12 12:51:35 -06:00
DRC
713c451f58 Enable SSE2 progressive Huffman encoder for x32
Referring to #289, I'm not sure where I arrived at the conclusion that
the SSE2 progressive Huffman encoder doesn't provide any speedup for
x32.  Upon re-testing, I discovered it to be about 50% faster than the
C encoder.

This commit also re-purposes one of the CI tests (specifically, the
jpeg-7 API/ABI test) so that it tests x32 as well.
2019-11-08 16:03:38 -06:00
DRC
2234deeeed Fix MSan use-of-uninitialized-value error
... introduced by 42825b68d5.  In fact,
fault-tolerant multi-scan block smoothing cannot currently be used with
the arithmetic decoder, because that decoder doesn't have any way of
distinguishing a normal end of scan from an unexpected end of scan.
Thus, this commit also modifies the change log to reset the expectations
regarding the scope of the fault-tolerant multi-scan block smoothing
feature.  If, at some point in the future, the arithmetic decoder can be
modified to detect an unexpected end of scan, then one would need only
set entropy->pub.insufficient_data = TRUE when the arithmetic decoder
encounters an unexpected end of scan in order to make fault-tolerant
block smoothing work properly with that decoder.
2019-11-08 13:51:34 -06:00
DRC
82695cfddf ChangeLog: Acknowledge 2.0.3/de-acknowledge 2.0.4
It is very unlikely that there will be an official 2.0.4 release.
2019-11-07 15:15:36 -06:00
DRC
42825b68d5 Fault-tolerant multi-scan block smoothing
This commit modifies the behavior of the block smoothing algorithm in
the libjpeg API library so that, if a scan in a multi-scan JPEG image is
incomplete (due to premature termination of the image stream), the block
smoothing parameters from the previous (complete) scan are used to
smooth any iMCU rows that the incomplete scan does not contain.

Closes #343
2019-11-07 15:12:54 -06:00
DRC
f2d4b47315 Travis: Use Docker tag that matches Git branch
dcommander/buildljt:dev is a CentOS 6 container with YASM 1.2.0 rather
than NASM 2.10, so it can build the new optimized SSE2 Huffman encoder.
2019-11-07 03:07:17 -06:00
DRC
45dff48c9f Merge branch 'master' into dev 2019-11-06 23:02:03 -06:00
DRC
622c462e48 Fix copyright header formatting buglets 2019-11-06 17:24:34 -06:00
DRC
410c028f33 example.txt: Avoid undefined setjmp() behavior
Modifying a locally-defined non-volatile variable below the setjmp()
return point results in undefined behavior whereby the variable may not
have the expected value after setjmp() returns.

Fixes #379
2019-11-06 16:16:54 -06:00
DRC
d70047fcd2 Travis: Use GCC 6 for Mac pre-release builds
The primary impetus for this is to eliminate build warnings, such as

  (32-bit only)
  section "__textcoal_nt" is deprecated

  object file (XXXXXX.o) was built for newer OSX version (10.XX) than
  being linked (10.5)

Upgrading to GCC 6 results in neutral performance for compression,
a measured average overall decompression speedup of 2.5% for 64-bit
code, and a measured average overall decompression speedup of -4.3% for
32-bit code on a 3 GHz Core i7.  The 4.3% slow-down for 32-bit code is
deemed acceptable, given that 32-bit macOS apps are deprecated.
2019-11-05 17:57:59 -06:00
DRC
cbf0fcc8b7 i386 SSE2 Huffman: Fix pointer arithmetic issue
Splitting the pointer arithmetic in GET_SYM() into a separate add and
sub instruction was an attempt to work around an error ("invalid operand
type") that occurred when assembling the file with NASM.  However, this
created a link error on macOS ("ld: illegal text-relocation to
'_jconst_huff_encode_one_block' in
simd/CMakeFiles/simd.dir/i386/jchuff-sse2.asm.o from
'_jsimd_huff_encode_one_block_sse2' in
simd/CMakeFiles/simd.dir/i386/jchuff-sse2.asm.o for architecture i386")
and also changed the alignment of the code in ways that might have
affected the previous benchmark results (which took a great deal of time
to obtain.)  Ultimately, the path of least resistance is just to
require NASM 2.13 or later.
2019-11-05 15:56:28 -06:00
DRC
bbedb4b564 Merge branch 'master' into dev 2019-11-05 15:43:21 -06:00
DRC
cf54623b08 Mac: Support hiding SIMD fct symbols w/ NASM 2.14+
(NASM 2.14+ now supports the private_extern section directive, which was
previously only available with YASM.)
2019-11-05 15:41:59 -06:00
DRC
087c29e07f Optimize Huffman encoding
This commit improves the C and SSE2 Huffman encoding implementations in
the following ways:

- Avoid using xmm8-xmm15 in the x86-64 SSE2 implementation.  There is no
  actual need to use those registers, and avoiding them produces a
  cleaner WIN64 function entry/exit-- as well as shorter code, since REX
  prefixes can be avoided (this is helpful on certain CPUs, such as
  Intel Atom, for which instruction fetch and decoding can be a
  bottleneck.)
- Optimize register usage so that fewer REX prefixes and
  register-register moves are needed.
- Use the bit counter to store the number of free bits in the bit buffer
  rather than the number of bits in the bit buffer.  This changes the
  method for inserting a code into the bit buffer to:

  (put_buffer |= code << (free_bits -= code_size));

  As a result:
  * Only one bit counter needs to stay in a register (we just keep it in
    cl.)
  * The bit buffer contents are already properly aligned to be written
    out (after a byte swap.)
  * Adjusting the free bits counter and checking if the bit buffer is
    full can be combined into a single operation.
  * We can wait to flush the bit buffer until the buffer is actually
    full and not just in danger of becoming full.  Thus, eight bytes can
    be flushed at a time.

- Speed is quite sensitive to the alignment of branch target labels, so
  insert some padding and remove branches from the flush code.
  (Flushing this way isn't actually faster when compared to using
  branches, but the branchless code doesn't need extra alignment and is
  thus smaller.)
- Speculatively write out the bit buffer as a single 8-byte write,
  falling back to a byte-by-byte write only if there are any 0xFF bytes
  in the bit buffer that need to be encoded as 0xFF 0x00.
- Use MMX registers for the 32-bit implementation (so the bit buffer can
  be 64 bits wide.)
- Slightly reduce overall function code size.
- Eliminate or combine a few SSE instructions.
- Make some minor improvements to instruction scheduling.
- Adjust flush_bits() in jchuff.c to handle cases in which the bit
  buffer has less than 7 free bits (apparently that couldn't happen
  before.)

Based on:
947a09defa
262ebb6b81
6e9a091221

See change log for performance claims.

Closes #292
2019-11-04 19:04:05 -06:00
DRC
d92ae5df0c Merge branch 'master' into dev 2019-11-04 18:50:45 -06:00
DRC
ac59b2c582 TJBench: Fix output with -componly -quiet 2019-11-04 18:49:46 -06:00
DRC
6902cdb177 Build: Don't require ASM_NASM if !REQUIRE_SIMD
The build system is supposed to fall back to a non-SIMD build if
WITH_SIMD==1 but REQUIRE_SIMD==0.

Based on:
972df912d0

Closes #384
2019-10-29 12:08:40 -05:00
DRC
adf9cc942f j*huff.c: Remove crufty ASSIGN_STATE() macro
This macro is a relic of libjpeg's historic need to support a wide
variety of C compilers with varying degrees of compatibility.  Such was
necessary during the open systems era, because C compilers were often
supplied by the system vendor.  Prior to 1989, there was no C standard
per se, and even after ANSI C became a thing, there were still compilers
in use that didn't conform to it (libjpeg was first released in 1991.)

Realistically, only a handful of C compilers are in widespread use these
days, and all modern C compilers should support structure assignment.
2019-10-24 02:13:34 -05:00
DRC
95f4d6ef8b Merge branch 'master' into dev 2019-10-24 02:13:23 -05:00
DRC
55de97207d AppVeyor: Use MinGW-builds instead of MSYS2 MinGW
... to avoid backward compatibility issues with GCC 4-6 MinGW
toolchains.  Apparently GCC 7+ MinGW toolchains introduce a link-time
dependency with internal MinGW CRT functions that are meant to provide
compatibility with Microsoft's Universal CRT (ucrt) library, but those
internal functions are not available in GCC 4-6 MinGW toolchains.  This
made it impossible to use the official builds of libjpeg.a and
libturbojpeg.a with GCC 4-6 MinGW toolchains (a fatal link error--
"undefined reference to '__imp___acrt_iob_func'"-- occurred.)

This problem was not immediately apparent after switching to the MSYS2
implementation of MinGW (d6d7b53968)
because, for a while, MSYS2 was still using GCC 5 and 6.

Refer to libjpeg-turbo/libjpeg-turbo#382
2019-10-24 02:04:04 -05:00
DRC
708f013f89 Win packaging: Fix 64-bit VC/GCC co-install issue 2019-10-23 00:31:30 -05:00
DRC
163f0b1965 Bump version to 2.0.4 to prepare for new commits 2019-10-22 19:39:38 -05:00
DRC
3a32d199df x86 SIMD: Consistify capitalization of NASM types
byte, word, dword, qword, oword, and yword are all assembler keywords,
so it makes sense to use lowercase for these so as not to mistake them
for macros or constants.
2019-10-17 20:02:20 -05:00
DRC
9a51a87af3 x86 SIMD: Remove obsolete [TAB8] comments
With apologies to Richard Hendricks, our assembly code no longer uses
tabs.
2019-10-17 14:11:35 -05:00
DRC
74aeaddf8e jc*huff.c: Consistify preproc directive formatting
The rest of the libjpeg API code uses "#if defined(condition)" rather
than "#if defined condition".
2019-10-17 14:09:50 -05:00
DRC
2ae2bd66b4 Remove support for Apple's Java implementation
(AKA "Java for OS X systems.")  This implementation of Java 1.6 is long
obsolete and not supported on any version of macOS past High Sierra.
Oracle no longer provides a 32-bit JVM on macOS, so it is no longer
necessary to provide a 32-bit version of the TurboJPEG Java wrapper on
macOS.
2019-10-04 16:31:46 -05:00
DRC
b7523059c1 Merge branch 'master' into dev 2019-10-04 15:53:30 -05:00
DRC
ab6c4a5db1 Travis: Fix macOS build
Java 6 has moved to homebrew/cask-versions.
2019-10-04 15:02:18 -05:00
DRC
ec4cacc16e BUILDING.md: Document need for CRB/PowerTools repo
NASM and YASM are located in this non-default repository on
(respectively) RHEL and CentOS.
2019-10-02 16:42:03 -05:00
DRC
b4110b65fc Merge branch 'master' into dev 2019-09-04 18:58:12 -05:00
DRC
5db6a6819d README.md: Document memory debugger pitfalls
(more specifically, the need to disable libjpeg-turbo's SIMD extensions
when testing with valgrind, MSan, etc.)

Addresses a concern expressed in #365
2019-08-30 12:02:50 -05:00
DRC
f448279b14 README.md: Remove vestigial autotools references 2019-08-30 11:24:36 -05:00
DRC
ded5a504b4 tjDecodeYUV*: Fix err if TJ inst used for prog dec
If the TurboJPEG instance passed to tjDecodeYUV[Planes]() was previously
used to decompress a progressive JPEG image, then we need to disable the
progressive decompression parameters in the underlying libjpeg instance
before calling jinit_master_decompress().

This commit also modifies the build system so that the "tjtest" target
will test for this issue, and it corrects a previous oversight in the
build system whereby tjbenchtest did not test progressive
compression/decompression unless WITH_JAVA was true.
2019-08-15 13:57:36 -05:00
DRC
8ef53b102f Merge branch 'master' into dev 2019-08-14 22:08:59 -05:00
DRC
c0d0fe86d8 ChangeLog.md: Wordsmithing 2019-08-14 22:08:44 -05:00
DRC
a81a8c137b SSE2 SIMD: Fix prog Huffman enc. error if Sl%16==0
(regression introduced by 5b177b3cab)

The SSE2 implementation of progressive Huffman encoding performed
extraneous iterations when the scan length was a multiple of 16.

Based on:
bb7f1ef983

Fixes #335
Closes #367
2019-08-14 22:01:30 -05:00
DRC
02f7bcdbd1 Travis: Enable additional sanitizer tests
- Re-purpose the non-SIMD test to test with MSan as well.
- Re-purpose the ASan test to test with UBSan as well.
- Use the default Travis build environment rather than specifying Ubuntu
  14.04.  I think I added 'dist: trusty' back when 14.04 was newer than
  the default, but now it's older than the default.
- Enable verbose output for any unit tests that fail (so we can see the
  sanitizer output.)
2019-08-13 16:15:00 -05:00
Hugo Locurcio
bbb7550709 Improve grammar in cjpeg's -nojfif help message 2019-08-12 18:48:12 +01:00
DRC
7fbfe29c65 Merge branch 'master' into dev 2019-07-18 15:18:27 -05:00
DRC
5ced1f590b Travis: Cache Homebrew downloads
... to speed up the Mac CI builds.
2019-07-18 15:17:33 -05:00
DRC
b98ee19241 Travis: Update Homebrew/fix Mac CI build
Updating Homebrew wasn't necessary when the CI build first started using
the xcode8.3 image (see c8e52741fd), but
apparently it now is.
2019-07-18 14:14:47 -05:00
DRC
ad8330af72 TJBench.java: Remove space in method invocation
(to make checkstyle happy)
2019-07-12 17:29:27 -05:00
DRC
b25adabcfa tjbench.c: Fix minor code formatting errors
(introduced by 2a9e3bd743)
2019-07-12 17:28:15 -05:00
DRC
875e873f26 tjutil.c: Fix compiler warning with Visual Studio
Apparently windows.h includes stdlib.h, which defines the max() and
min() macros, so we need to ensure that tjutil.h is included after
that.
2019-07-11 17:06:08 -05:00
DRC
2a9e3bd743 TurboJPEG: Properly handle gigapixel images
Prevent several integer overflow issues and subsequent segfaults that
occurred when attempting to compress or decompress gigapixel images with
the TurboJPEG API:

- Modify tjBufSize(), tjBufSizeYUV2(), and tjPlaneSizeYUV() to avoid
  integer overflow when computing the return values and to return an
  error if such an overflow is unavoidable.
- Modify tjunittest to validate the above.
- Modify tjCompress2(), tjEncodeYUVPlanes(), tjDecompress2(), and
  tjDecodeYUVPlanes() to avoid integer overflow when computing the row
  pointers in the 64-bit TurboJPEG C API.
- Modify TJBench (both C and Java versions) to avoid overflowing the
  size argument to malloc()/new and to fail gracefully if such an
  overflow is unavoidable.

In general, this allows gigapixel images to be accommodated by the
64-bit TurboJPEG C API when using automatic JPEG buffer (re)allocation.
Such images cannot currently be accommodated without automatic JPEG
buffer (re)allocation, due to the fact that tjAlloc() accepts a 32-bit
integer argument (oops.)  Such images cannot be accommodated in the
TurboJPEG Java API due to the fact that Java always uses a signed 32-bit
integer as an array index.

Fixes #361
2019-07-11 16:56:50 -05:00
DRC
f37b7c1f96 Build: Fix build/install with Xcode IDE
Closes #355
2019-07-02 11:28:26 -05:00
Jonathan Wright
509c2680aa Use bias pattern for 4:4:0 (h1v2) fancy upsampling
This commit modifies h1v2_fancy_upsample() so that it uses an ordered
dither pattern, similar to that of h2v1_fancy_upsample(), rounding up or
down the result for alternate pixels rather than always rounding down.
This ensures that the decompression error pattern for a 4:4:0 JPEG image
will be similar to the rotated decompression error pattern for a 4:2:2
JPEG image.  Thus, the final result will be similar regardless of
whether a 4:2:2 JPEG image is rotated or transposed before or after
decompression.

Closes #356
2019-07-02 09:55:24 -05:00
Kornel
d48cfe591f Disable PNG on Windows 2019-06-18 00:00:38 +01:00
Diego Sanchez
68564c0f9e Adds extern "C" to transupp.h 2019-05-30 14:18:52 +02:00
DRC
ec5adb83dd Build/packaging: Support macOS package/DMG signing 2019-05-18 17:58:50 -05:00
Kornel
de4cbb5c21 Default to PNG enabled 2019-05-18 17:39:48 +01:00
DRC
051f4862f9 Travis: Fix iOS build
The new libjpeg-turbo 2.1.x official build scripts expect Xcode to be
under /Applications/Xcode83.app.
2019-05-09 20:46:18 -05:00
DRC
c055c88057 Discontinue support for 32-bit iOS builds 2019-05-09 20:36:51 -05:00
DRC
85d96d4478 Merge branch 'master' into dev 2019-05-09 19:13:39 -05:00
DRC
c8e52741fd Travis: Use xcode8.3 image
xcode7.3 is based on El Capitan, which is EOL, and Homebrew no longer
provides El Cap bottles (pre-compiled binaries.)  Thus, Homebrew was
trying to build GCC 5, YASM, and the other packages we need from source,
which caused the Mac CI builds to time out.  I tried goading Homebrew
into installing GCC 5.5.0_2 and YASM 1.3.0_1, which still have El Cap
bottles available, by using the URLs of those specific versions of the
formulae (from the Homebrew GitHub repository) as package names.  This
failed, however, because 'brew bundle' converted the URLs to all
lowercase.  I then tried explicitly installing the old formulae by using
'brew install' with the aforementioned URLs (bypassing the Travis
Homebrew addon), but Homebrew still tried to build all of the
dependencies from source.

Upgrading to Xcode 8.3.x necessitated regression testing the performance
on iOS, but that proved less of a pain than figuring out how to install
all of the old Homebrew bottles we needed.  Also, this future-proofs the
CI builds against the inevitable discontinuation of the xcode7.3 image.

Note that Xcode 8.3.x improves iOS 64-bit decompression performance
significantly relative to Xcode 7.2.x or 7.3.x.  iOS 32-bit performance
unfortunately regresses by as much as 5%, but it can't be helped (32-bit
iOS apps are no longer supported on iOS 11+ anyhow, and the next major
release of libjpeg-turbo will remove support for them as well.)
2019-05-09 18:09:42 -05:00
Kornel
72473266b8 Fix appveyor link 2019-04-24 15:56:40 +01:00
Kornel
a5ad46b9f8 Change unsupported format message
To be sure it's not coming from the old cjpeg
2019-04-24 15:54:33 +01:00
DRC
f36d531553 Merge branch 'master' into dev 2019-04-23 14:54:23 -05:00
DRC
6399d0a699 Fix code formatting/style issues ...
... including, but not limited to:
- unused macros
- private functions not marked as static
- unprototyped global functions
- variable shadowing

(detected by various non-default GCC 8 warning options)
2019-04-23 14:15:48 -05:00
Chris Blume
aa9db61677 x86 SIMD: Check for CPUID leaf 07H before using
According to Intel's manual [1], "If a value entered for CPUID.EAX is
higher than the maximum input value for basic or extended function for
that processor then the data for the highest basic information leaf is
returned."

Right now, libjpeg-turbo doesn't first check that leaf 07H is supported
before attempting to use it, so the ostensible AVX2 bit (Bit 05) of the
CPUID result might actually be Bit 05 from a lower leaf.  That bit might
be set, even if the CPU doesn't support AVX2.

This commit modifies the x86 and x86-64 SIMD feature detection code so
that it first checks whether CPUID leaf 07H is supported before
attempting to use it to check for AVX2 instruction support.

DRC:
This commit should fix
https://bugzilla.mozilla.org/show_bug.cgi?id=1520760
However, I have not personally been able to reproduce that issue,
despite using a Nehalem (pre-AVX2) CPU on which the maximum CPUID leaf
has been limited via a BIOS setting.

Closes #348

[1]
"Intel® 64 and IA-32 Architectures Software Developer's Manual, Volume 2 (2A, 2B, 2C & 2D): Instruction Set Reference, A-Z", https://software.intel.com/sites/default/files/managed/a4/60/325383-sdm-vol-2abcd.pdf, page 3-192.
2019-04-16 17:07:28 -05:00
DRC
8a0e35b212 Merge branch 'master' into dev 2019-04-15 13:41:45 -05:00
DRC
2b05d47bc2 ChangeLog.md: Document 33011754 2019-04-15 13:38:15 -05:00
DRC
7bc9fca430 jdhuff.c: Silence UBSan signed int overflow err #2
Same as d3a3a73f64 but in the fast decode
path.  It was necessary to use a different-sized test image in order to
trigger the error in this location.

Refer to #347
2019-04-12 09:09:27 -05:00
DRC
bb16b94455 GitHub: Remove new lines from feature-request.md
(to make checkstyle happy)
2019-04-12 08:54:16 -05:00
DRC
33011754e6 Android: Fix "using JNI after critical get" errors
5ea77d8b77 was insufficient to fix all of
these.  In particular, we need to always release the primitive arrays
before throwing an exception, because throwing an exception qualifies as
"using JNI."

Refer to #300
2019-04-12 08:49:27 -05:00
DRC
bce58f487e Consistify formatting of macros in TurboJPEG code 2019-04-12 07:49:35 -05:00
DRC
ce067a6cd1 GitHub: Template tweaks
CONTRIBUTING.md: Correct misuse of "as such" (Grammar Police)

bug-report.md: Clarify that the submitter should always test against the
latest stable code base.
2019-04-10 15:20:46 -05:00
DRC
d3a3a73f64 jdhuff.c: Silence UBSan signed int overflow error
Some pathological test images have been created that can cause s to
overflow or underflow the signed int data type during decompression.
This is technically undefined behavior according to the C spec, although
every modern implementation I'm aware of will treat the signed int as a
2's complement unsigned int, thus causing the value to wrap around to
INT_MIN if it exceeds INT_MAX.  This commit simply makes that behavior
explicit in order to shut up UBSan.  At least when building for x86-64
or i386 using Clang or GCC, this commit does not change the
compiler-generated assembly code at all.

The code that triggered this error has existed in the libjpeg code base
for at least 20 years (and probably much longer), so the fact that it
hasn't produced a user-visible problem in all of that time strongly
suggests that UBSan is being overly pedantic here.  But if someone can
cough up a platform that doesn't wrap around to INT_MIN when 1 is added
to INT_MAX, then I'll happily change my opinion.

Fixes #347
2019-04-10 14:57:12 -05:00
DRC
58a3975e93 Bump version to 2.0.3 to prepare for new commits 2019-04-10 14:57:12 -05:00
Mozilla-GitHub-Standards
351d5d08fa Add Mozilla Code of Conduct file
Fixes #330.

_(Message COC002)_
2019-03-28 23:12:17 +00:00
Kornel
426de82d0c Bump version
Due to CMake change
2019-03-15 12:49:56 +00:00
DRC
5857929f95 GitHub: Formatting tweak to CONTRIBUTING.md 2019-03-05 17:48:20 -06:00
DRC
709477274e GitHub: Tweak bug report template 2019-03-01 13:13:27 -06:00
DRC
1af712c101 GitHub: Add feature request template 2019-03-01 13:11:11 -06:00
DRC
ec90cd0f90 GitHub: Add contributor guidelines 2019-03-01 12:57:28 -06:00
DRC
ce76ffac4c GitHub: Add bug report template 2019-03-01 10:07:51 -06:00
DRC
afbe48c290 MMI: Support 32-bit Loongson architectures 2019-02-27 13:36:48 -06:00
DRC
98ff5507d8 MMI: Fix bug in jsimd_h2v1_merged_upsample_mmi()
... that occurred when ((image width) & 1) != 0.
2019-02-27 13:36:48 -06:00
DRC
3ca6dba96e Merge branch 'master' into dev 2019-02-17 09:33:57 -06:00
DRC
500b5ecec3 turbojpeg.c: Fix compiler warning w/ -DNO_GETENV 2019-02-17 09:06:42 -06:00
DRC
87ab3360d0 appveyor.yml: Cache NASM binary package
... since www.nasm.us seems to be down frequently.  This doesn't help us
at the moment, but hopefully once the site is back up this will prevent
future build failures.
2019-02-14 10:01:16 -06:00
Chris Blume
b46af82cc1 ARMv7 NEON: #ifdef unused funcs/vars w/ -mfpu=neon
When simd/arm/jsimd.c is compiled with __ARM_NEON__ defined (which will
be the case if -mfpu=neon is passed to the compiler), the
parse_proc_cpuinfo() and check_feature() functions and the bufsize
variable are unused and thus need to be #ifdef'ed out in order to avoid
compiler warnings.  Note that the bufsize variable was already #ifdef'ed
out on Linux but not on Android due to lack of parentheses (&& takes
precedence over ||.)

Closes #331
2019-02-14 08:53:49 -06:00
DRC
a4aa30d9a0 ChangeLog.md: "floating-point"="floating point" 2019-02-13 22:03:31 -06:00
DRC
aaf58dabb6 Merge branch 'master' into dev 2019-02-13 17:05:26 -06:00
DRC
0d7818d1b6 rpm.spec.in: Fix "File listed twice" warning/error
%{_libdir}/pkgconfig is a directory and should thus be prefixed by
%{dir} (oops.)  This issue caused the debuginfo build under RHEL 8
(which is apparently now enabled by default-- regardless of whether the
RPM actually contains debug info, but that's another matter) to fail
with:

RPM build errors:
  File listed twice: /opt/libjpeg-turbo/lib64/pkgconfig/libjpeg.pc
  File listed twice: /opt/libjpeg-turbo/lib64/pkgconfig/libturbojpeg.pc
2019-02-13 17:04:46 -06:00
DRC
4b67db4d9b rpm.spec.in: Fix doc packaging issues w/ RHEL 7+
On RHEL 7 and later (not sure exactly whether this is a product of the
newer RPM release or something distro-specific), macros are lazily
expanded, so we need to set _docdir using %global (which expands at
definition time) and prior to _prefix and _datarootdir (which affect
_defaultdocdir.)  Otherwise, _docdir is set to a subdirectory of
/opt/libjpeg-turbo/share/doc or /opt/libjpeg-turbo/doc.  The former
(which happens on RHEL 7) leads to incorrect documentation packaging
(the docs should be packaged under /usr/share/doc per Red Hat
standards), and the latter (which happens on RHEL 8) leads to an RPM
build error.
2019-02-13 17:04:28 -06:00
DRC
f70a7e1ee1 rpm.spec.in: Update deprecated [Build]Prereq tags
AFAICT, Requires and BuildRequires subsumed the functionality of Prereq
and BuildPrereq in RPM 4.0, and none of the platforms we support with
libjpeg-turbo 2.0.x has RPM < 4.4.
2019-02-13 17:02:32 -06:00
Leonard Hecker
f27167f20c Fixed broken PNG_SUPPORTED flag (#326) 2019-02-13 19:42:25 +00:00
DRC
a9075a17c3 Merge branch 'master' into dev 2019-02-12 13:42:57 -06:00
DRC
6a8421fb44 GNUInstallDirs.cmake: Silence CMP0054 warning ...
in CMake 3.11 and later
2019-02-12 13:40:14 -06:00
DRC
031e16ecff tjbench.c: Fix GCC 8 compiler warning 2019-02-11 22:46:04 -06:00
DRC
75be88cfbd Build: Optionally install PDB files for MSVC DLLs
Based on
333a36ae98

Closes #329
Closes #324
2019-02-11 13:10:09 -06:00
DRC
bdec995839 MMI: Fix unaligned decomp. perf. for 32-bit PFs
(Oversight from db84125fcb)
2019-02-01 01:16:13 -06:00
DRC
fa905fbf7b MMI: Use unaligned stores w/ merged upsampling
... when necessary.  This was an oversight from
2f9e7c84d1
2019-02-01 01:03:32 -06:00
DRC
9aada25ced Merge branch 'master' into dev 2019-02-01 01:02:55 -06:00
DRC
e2442e0707 MMI: Fix unaligned comp. perf. for 32-bit PFs also
(Oversight from 1c2d3cfaaf)
2019-02-01 00:59:58 -06:00
DRC
73fd604161 MMI: Fix formatting issue detected by checkstyle 2019-02-01 00:24:09 -06:00
DRC
2f9e7c84d1 Loongson MMI h2v1 and h2v2 merged upsampling
Based on:
e8f5cee5aa
2019-01-31 23:18:48 -06:00
DRC
3c7199ff06 Loongson MMI h2v1 fancy upsampling
Based on:
e8f5cee5aa
2019-01-31 17:01:01 -06:00
DRC
73b98acd8b Loongson MMI RGB-to-Grayscale conversion
Based on:
e8f5cee5aa
2019-01-31 16:44:55 -06:00
DRC
bb0d170288 Improve readability of Loongson MMI code
We have more than eight registers to work with, as well as three-operand
intrinsics, so there's no need for the implementation to be such a
literal port of the MMX code.
2019-01-31 16:44:48 -06:00
DRC
db84125fcb MMI: Use aligned store instructions when possible
This improves decompression performance by 2-5%.
2019-01-31 15:30:58 -06:00
DRC
ae4221f905 Loongson MMI fast forward/inverse DCT
Based on:
32a9ca222d
2019-01-31 15:30:58 -06:00
DRC
674343ab14 Merge branch 'master' into dev 2019-01-31 15:30:25 -06:00
DRC
1c2d3cfaaf MMI: Fix comp. perf. issue w/ unaligned image rows
Using ldc1 with a non-64-bit-aligned memory location causes as much as a
10x slow-down in overall compression performance.
2019-01-31 15:30:05 -06:00
DRC
2d0b675adf Build: Fix install of static build w/ VStudio IDE
Unfortunately, this hack is necessary because:
- install(TARGETS, ...) doesn't support the RENAME option.
- We can't modify OUTPUT_NAME for the "-static" targets without breaking
  the regression tests.
- ${CMAKE_CFG_INTDIR} doesn't seem to work properly in an install()
  command.

Refer to #307
2019-01-25 16:54:10 -06:00
DRC
6fac90945a wrbmp.c, wrtarga.c: Remove unused variables
(should have been done with the previous commit)
2019-01-23 16:18:41 -06:00
DRC
01e3032354 Eliminate support for compilers w/o unsigned char
libjpeg-turbo has never really supported such compilers, since (AFAIK)
they are non-existent on any modern computing platform and thus
impossible for us to test.  (Also, the TurboJPEG API would break without
unsigned chars.)

Furthermore, the unified CMake-based build system introduced in 2.0
always defines HAVE_UNSIGNED_CHAR, so retaining other code paths is
pointless.  Eliminating support for compilers without unsigned char
eliminates the need for the GETJSAMPLE() macro, which improves the
readability of many parts of the code as well as improving the
performance of writing Targa and Windows BMP files.

Fixes #317
2019-01-23 15:12:26 -06:00
Kornel
a214094b37 Update README.md 2019-01-23 17:36:50 +00:00
Ewout ter Hoeven
83fcf7b9e9 Fix Appveyor configuration (#323)
* Fix cmake target and re-add msbuild
2019-01-23 17:24:30 +00:00
DRC
42d62bf114 Merge branch 'master' into dev 2019-01-23 11:20:11 -06:00
Kornel
8a885c5443 Update appveyor.yml 2019-01-23 17:18:04 +00:00
Ewout ter Hoeven
ae5c15eb59 Add continuous integration on Windows with AppVeyor (#322)
* Create appveyor.yml
2019-01-23 17:10:19 +00:00
DRC
90e2d7f3fd LICENSE.md: Clarifications RE: BSD & zlib licenses
Including the license templates was confusing to some, since it made
it appear as if the copyright year and author were unspecified for the
libjpeg-turbo source.  Thus, rather than include the zlib License
template, link to that template on opensource.org.  For the Modified BSD
License, include a roll-up of copyright years and authors, since the
terms of that license require the text of it to be included in product
documentation for binary distributions without accompanying source code.
2019-01-23 09:01:33 -06:00
DRC
5308c1a03b BUILDING.md: Update/simplify Android build instr.
Use the android.toolchain.cmake toolchain file in the NDK (v13b or
later), since this toolchain file generally takes care of setting the
approprate compiler flags and dealing with the differences between
GCC and Clang.  Our custom Android build procedure did not work with
Clang-based NDK toolchains, which meant that it could not be made to
work with NDK v18b or later.

Fixes #309
2019-01-22 12:20:26 -06:00
Orivej Desh
ce90ab5d44 Build: Fix regression test failure w/ ctest -j
The djpeg rgb-islow-icc-cmp test must run after the djpeg rgb-islow
test, since the latter generates testout_rgb_islow.icc.
2019-01-21 16:56:56 -06:00
DRC
1ee87a9e2e djpeg: Fix PPM output regression w/ color quant.
Regression caused by aa7459050d

Fix based on:
03fbacb8eb

Closes #310
2019-01-21 16:33:49 -06:00
DRC
479501b07c TurboJPEG: Decompress 4:4:4 JPEGs with unusual SFs
Normally, 4:4:4 JPEGs have horizontal x vertical luminance & chrominance
sampling factors of 1x1.  However, it is technically legal to create
4:4:4 JPEGs with sampling factors of 2x1, 1x2, 3x1, or 1x3, since the
sums of the products of those sampling factors are still <= 10.  The
libjpeg API correctly decodes such images, so the TurboJPEG API should
as well.

Fixes #323
2019-01-21 14:26:00 -06:00
DRC
a39c970d27 Merge branch 'master' into dev 2019-01-01 21:53:19 -06:00
DRC
12f3d0be84 Merge branch 'master' into dev 2019-01-01 21:52:21 -06:00
Stephen
9bc8eb6449 Travis: Use Homebrew addon to improve performance 2019-01-01 21:36:03 -06:00
DRC
0fa5ae6b54 TJBench Java: Properly handle transform warnings
+ warnings from TJDecompressor.decompressHeader()
2019-01-01 21:16:33 -06:00
DRC
1ff90822f1 TJBench: Fix FPE when decompressing 0-width JPEG
Fixes #319
2019-01-01 21:14:50 -06:00
DRC
f8cca819a4 wrbmp.c: Don't allow quantization w/ non-RGB CS
If cinfo->quantize_colors == 1, then jpeg_calc_output_dimensions() will
set cinfo->output_components to 1, and if cinfo->out_color_space is not
RGB (or extended RGB), hilarity will ensue.

Fixes #305
2019-01-01 20:48:14 -06:00
DRC
beefb62a6f wrbmp.c: Use IsExtRGB() macro where appropriate
(to improve readability)
2019-01-01 20:48:14 -06:00
DRC
3d9c64e9f8 tjLoadImage(): Fix int overflow/segfault w/big BMP
Fixes #304
2019-01-01 20:48:09 -06:00
DRC
23e8e0ff83 jversion.h: Bump copyright year to 2019 2019-01-01 18:59:59 -06:00
DRC
c868e41b22 Build: Fix regr. that nuked RPATH in Mac/iOS build
Caused by 950580eb0c.  Since the code that
sets CMAKE_INSTALL_RPATH now depends on ENABLE_SHARED, that code needed
to be moved to after the point at which ENABLE_SHARED is defined.
2019-01-01 18:59:53 -06:00
DRC
0696b0a451 Bump version to 2.0.2 to prepare for new commits 2019-01-01 13:55:01 -06:00
Gary Zhang
254909fab5 fix issue #315 jddctmgr.c contains mixed declaration, which MSVC can't accept. 2018-11-30 10:19:05 +00:00
DRC
aa829dcf50 Travis: Fetch GPG key from libjpeg-turbo.org
I give up on the public keyserver.  It inexplicably just fails
sometimes.  I was trying to use it out of an abundance of caution
(<cough> paranoia <cough>), but it seems like most open source projects
just serve up their public keys from their project web sites.  The
private and public pre-release keys are still stored on separate sites,
the private key is still strongly encrypted by Travis, and we use a
separate key for pre-releases anyhow, so even if it's compromised, we
can quickly and easily deploy a new one.
2018-11-20 22:52:36 -06:00
Kornel
fbef50bc8b Removed broken link 2018-11-15 18:11:56 +00:00
DRC
43ce78e032 Build: Fix issue with HAVE_MAPFILE test on Solaris
We have to link the test code into a shared library, or else the mapfile
prevents necessary libc symbols from being exposed.
2018-11-15 11:54:20 -06:00
Kornel
add6158e96 Merge pull request #275 from mozilla/idct-selector
Make IDCT method customizable
2018-11-15 16:05:51 +00:00
Kornel
65aaecd2d5 Link with libm 2018-11-15 15:17:17 +00:00
Kornel
cfb7138523 Update readme 2018-11-14 00:10:13 +00:00
DRC
2cc4f93c88 Merge branch 'master' into dev 2018-11-12 14:40:19 -06:00
DRC
bb3d325624 Travis: Try high-availability SKS keyserver pool
The saga continues ...
2018-11-12 13:20:28 -06:00
DRC
c701014dce tjbench.c: Fix compiler warnings with GCC 8
strncpy() may fail to truncate dst if len == strlen(dst).
2018-11-12 12:27:23 -06:00
DRC
950580eb0c Build: Fix install error with fully static build
Closes #273
2018-11-12 11:22:48 -06:00
Kornel
8217fd5478 Merge tag '2.0.0'
* tag '2.0.0': (160 commits)
  Clarify Android Windows build instructions
  Bump revision to 2.0.0
  Build: Don't use @rpath with OS X 10.4 builds
  Fix JPEG spec references per ISO/ITU-T suggestions
  Fix int overflow when decompr. corrupt prog. JPEG
  cjpeg: Fix OOB read caused by malformed 8-bit BMP
  Build: Preserve CMake exe suffix from cmd line
  Honor CMake exe suffix when inst. static builds
  README.ijg: Clarification regarding JPEG 2000/XR
  BUILDING.md: Correct iOS/Android examples
  Build: Detect whether compiler supports DSPr2
  Fix jpeg_skip_scanlines() segfault w/merged upsamp
  Fix infinite loop in partial image decompression
  tjLoadImage(): Fix FPE triggered by malformed BMP
  TurboJPEG: Handle JERR_BMP*,JERR_PPM* error codes
  Fix CVE-2018-11813
  Travis: Use SKS keyserver pool
  Additional code formatting tweaks
  Java: Further style refinements
  Java: Reformat code per checkstyle recommendations
  ...
2018-11-11 16:13:59 +00:00
Hugo Cuvillier
103c6c3276 Adds initial mozjpeg.podspec 2018-11-10 15:47:08 +00:00
DRC
2b1c9c6887 Travis: Don't check key server SSL certificate
... when downloading the RPM signing key.  Apparently the key server
URL sometimes redirects to an https URL, which may explain why fetching
the RPM signing keys failed frequently when we used to run wget inside
of the CentOS 5 Docker container.
2018-11-02 11:55:29 -05:00
DRC
07e304c3bf Travis: Work around frequent build failures
The build will consistently fail for days at a time with:

error: http://pool.sks-keyservers.net/pks/lookup?op=get&search=0x0575F26BD5B3FDB1: import read failed(-1).

I have a hunch that this is related to the CentOS 5 Docker container, so
this commit causes Travis to download the RPM signing key outside of
the container and share it with the container.
2018-10-26 09:29:09 -05:00
DRC
5ea77d8b77 Android: Fix "using JNI after critical get" error
We shouldn't be making JNI calls between GetPrimitiveArrayCritical() and
ReleasePrimitiveArrayCritical().  Apparently Android is stricter about
this than desktop Java.

Issue was introduced in 0713c1bb54.

Fixes #300
2018-10-26 08:58:31 -05:00
Kornel
9a1d32095b Merge pull request #308 from bolknote/master
Fix errors while build rpm package (CentOS 7.x)
2018-10-12 13:54:23 +01:00
Evgeny Stepanischev
17ed160078 Fix errors while build rpm package (CentOS 7.x) 2018-10-12 12:37:50 +03:00
DRC
504a295cde Include .pc files in LJT SDKs for Visual C++
These are apparently useful in certain esoteric build environments.

Closes #296
2018-10-11 15:13:34 -05:00
DRC
d00d7d8c19 cjpeg: Fix OOB read caused by malformed 8-bit TGA
... in which one or more of the color indices is out of range for the
number of palette entries.

Fix partly borrowed from jpeg-9c.

Fixes #295
2018-10-05 16:13:07 -05:00
DRC
aaffc14f65 Clarify that Win7 SP0 crash was a regression 2018-09-30 11:57:29 -05:00
DRC
d5f281b734 SIMD: Fix c000001d exception on Win 7 w/o SP1
Apparently Windows 7 without SP1 has O/S support for XSAVE but not for
YMM registers, and this exposed a bug in our usage of xgetbv.  The test
instruction will set ZF only if none of the bits match between the two
operarands, so in effect, we were enabling AVX2 instructions if the O/S
supported XSAVE and the CPU supported AVX2 but the O/S only supported
XMM registers.  This bug was not exposed on, for instance, Windows XP or
RHEL 5 because those O/S's do not support XSAVE.

Fixes #288
2018-09-28 16:23:14 -05:00
DRC
f2729c983a Build: Update javah target to work with JDK 10+
javah is no longer a thing, but 'javac -h' can accomplish the same task.
2018-09-21 15:50:08 -05:00
DRC
c1f07a9fc4 BUILDING.md: Correct/update Java information
- CMake 3.10.x or later must be used with JDK 11, or an error
  ("regex not supported") will occur when CMake tries to parse the Java
  version number.
- The JDK is no longer available at java.com.
2018-09-21 15:17:27 -05:00
DRC
133e4af070 Add x32 ABI support on Linux
The x32 ABI is similar to the x86-64 ABI but uses 32-bit pointers.
(Refer to https://sites.google.com/site/x32abi)

Based on:
8da8fc5213
1e33dfea80
24ffea78da
dedcf76753
d04228a7b5
b4ad38316a

Closes #274
2018-09-05 17:10:06 -05:00
DRC
995eb29dc3 Bump version to 2.1 alpha1
(to prepare for new features)
2018-09-05 09:08:00 -05:00
Rosen Penev
4f943644e5 Enable DSPr2 SIMD extensions if CPU type is mipsel
The DSPr2 extensions have been verified to work with little endian MIPS.
Whether or not CMAKE_SYSTEM_PROCESSOR is set to "mips" or "mipsel" in a
little endian MIPS environment seems to be inconsistent, but our build
system needs to handle both cases.
2018-09-04 21:17:58 -05:00
DRC
3bef88f6ec Fix MIPS DSPr2 build when using soft float ABI
(for instance, when passing -msoft-float to the compiler)

The instructions used by jsimd_quantize_float_dspr2() and
jsimd_convsamp_float_dspr2() don't work with the soft float ABI, so
disable those functions when soft float is enabled.

Based on:
129a739bfa

Closes #272
2018-09-04 18:03:00 -05:00
DRC
2260b66e16 jconfig.h: restore Autotools compatibility
(regression introduced with the CMake-based Un*x build system)

Refer to change log for more details.

Based on:
d992d12bc7

Closes #275
2018-08-31 17:39:52 -05:00
DRC
a861cc2f31 Bump version to 2.0.1 to prepare for new commits 2018-08-31 12:54:09 -05:00
Kornel
5c064c6ba5 Merge pull request #303 from garyzyg/issue-302
fix issue #302 rdpng.c contains mixed declaration, which MSVC can't a…
2018-08-24 12:50:24 +01:00
Gary Zhang
9454cd365a fix issue #302 rdpng.c contains mixed declaration, which MSVC can't accept. 2018-08-24 09:37:22 +08:00
luzpaz
43c58ff983 Correct various typos in code comments
Found via `codespell -q 3`

Closes #263
2018-07-31 16:59:16 -05:00
Konstantin Kopachev
86a9bd1b08 Prefer smaller file only on non-image changing operations
When cli arguments request image-changing operation (like transform, scans or arith coding) to be applied, force output result file, even if it has bigger filesize than original
2018-07-31 10:11:20 +01:00
Konstantin Kopachev
a4a721fce5 Only use mem-based io if it is supported 2018-07-31 10:11:20 +01:00
DRC
574f3a772c Clarify Android Windows build instructions
(must add .exe to CMAKE_C_COMPILER)

Addresses a concern raised in #245, #260
2018-07-27 11:47:48 -05:00
DRC
ad6c316146 Bump revision to 2.0.0 2018-07-25 11:03:20 -05:00
DRC
8d95be3afb Build: Don't use @rpath with OS X 10.4 builds
@rpath is only supported with 10.5 and later deployment targets.
libjpeg-turbo hasn't supported 10.4 "Tiger" since prior to 1.4, but I
still sometimes use the 10.4 SDK to test PowerPC code in a Snow Leopard
VM.
2018-07-24 21:32:16 -05:00
DRC
a62895265f Fix JPEG spec references per ISO/ITU-T suggestions
- When referring to specific clauses, annexes, tables, and figures, a
  "timed reference" (a reference that includes the year) must be used in
  order to avoid confusion.
- "CCITT" = "ITU-T"
- Replace ambiguous "JPEG spec" with the specific document number.
2018-07-24 18:43:49 -05:00
Even Rouault
9ab569e616 Fix int overflow when decompr. corrupt prog. JPEG
No discernible performance regression

Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9447
Credit to OSS Fuzz
Closes #259
2018-07-23 22:11:38 -05:00
DRC
9c78a04df4 cjpeg: Fix OOB read caused by malformed 8-bit BMP
... in which one or more of the color indices is out of range for the
number of palette entries.

Fix partly borrowed from jpeg-9c.  This commit also adopts Guido's
JERR_PPM_OUTOFRANGE enum value in lieu of our project-specific
JERR_PPM_TOOLARGE enum value.

Fixes #258
2018-07-20 19:57:43 -05:00
DRC
0fa7850aeb Build: Preserve CMake exe suffix from cmd line
Normally the value of CMAKE_EXECUTABLE_SUFFIX is clobbered by project().

This allows for specifying an executable suffix of .html with Emscripten
builds, which causes Emscripten to build standalone HTML versions of the
libjpeg-turbo test programs.
2018-07-20 12:21:20 -05:00
DRC
0c8eb5b4dd Honor CMake exe suffix when inst. static builds
This specifically allows an Emscripten (WASM) static build (for which
CMAKE_EXECUTABLE_SUFFIX=.js) to be properly installed.
2018-07-20 12:21:20 -05:00
DRC
84893085cf README.ijg: Clarification regarding JPEG 2000/XR
The sentence:
"Indeed, one of the original reasons for developing this free software
was to help force convergence on common, interoperable format standards
for JPEG files."
might be seen to imply that JPEG 2000 and JPEG XR are not interoperable
with themselves, although it is certainly the case that those formats
are not interoperable with each other, nor with
ITU T.81 | ISO/IEC 10918.  They are also certainly not as common as
ITU T.81 | ISO/IEC 10918, and (as an example) popular web browsers will
not display JPEG 2000 files.

The sentence in question was originally referring to proprietary,
non-standard formats and was meant to provide historical context.
libjpeg was originally released prior to the adoption of JFIF as an
official standard, so it encouraged adoption of JFIF as a de facto
standard by providing, under a business-friendly free software license,
a library for reading and writing images in that format.
2018-07-20 12:21:02 -05:00
DRC
f4b8a5cf03 BUILDING.md: Correct iOS/Android examples
toolchain.cmake should be created in the build directory, so the scripts
need to cd to that directory before generating that file.

Closes #254
2018-07-02 11:42:06 -05:00
DRC
6d8caa9f88 Build: Detect whether compiler supports DSPr2
This is basically the same test that was performed in acinclude.m4 in
the old autotools-based build system.  It was not ported to the
CMake-based build system because I previously had no way of testing
a non-DSPr2 build environment.

Fixes #248
2018-06-29 13:23:58 -05:00
Darrell Walisser
398c1e9acc Fix jpeg_skip_scanlines() segfault w/merged upsamp
Fixes NULL pointer reference when decompressing 4:2:2 or 4:2:0 JPEG
images with cinfo.do_fancy_upsampling = FALSE.

Closes #244
2018-06-24 19:04:19 -05:00
DRC
26f109290d Fix infinite loop in partial image decompression
... caused by using certain specific combinations of
jpeg_skip_scanlines() and jpeg_read_scanlines() calls with progressive,
vertically-subsampled JPEG images.

Fixes #237
2018-06-24 17:49:29 -05:00
DRC
43e84cff1b tjLoadImage(): Fix FPE triggered by malformed BMP
In rdbmp.c, it is necessary to guard against 32-bit overflow/wraparound
when allocating the row buffer, because since BMP files have 32-bit
width and height fields, the value of biWidth can be up to 4294967295.
Specifically, if biWidth is 1073741824 and cinfo->input_components = 4,
then the samplesperrow argument in alloc_sarray() would wrap around to
0, and a division by zero error would occur at line 458 in jmemmgr.c.

If biWidth is set to a higher value, then samplesperrow would wrap
around to a small number, which would likely cause a buffer overflow
(this has not been tested or verified.)
2018-06-12 21:17:34 -05:00
DRC
696e754ecf TurboJPEG: Handle JERR_BMP*,JERR_PPM* error codes
... in tjLoadImage()/tjSaveImage().  These error codes require an add-on
message table, and if it isn't initialized, then format_message()
produces "Bogus message code XXXX" instead.
2018-06-12 18:49:37 -05:00
DRC
909a8cfc7b Fix CVE-2018-11813
Refer to change log for details.

Fixes #242
2018-06-12 16:08:26 -05:00
Puyan Lotfi
7678cba140 Fixing compiler warning -Wmissing-prototypes
jdatadst.c:252:1: warning: no previous prototype for function 'jpeg_mem_dest_internal' [-Wmissing-prototypes]
2018-06-10 16:35:46 +03:00
Kornel
3820eb1e2d Merge pull request #290 from solvingj/patch-2
CMAKE_SOURCE_DIR -> CMAKE_CURRENT_SOURCE_DIR
2018-06-07 15:09:07 +01:00
Jerry
d23bf13189 CMAKE_SOURCE_DIR -> CMAKE_CURRENT_SOURCE_DIR
This change is proposed to enable cases where this library and it's CMakeLists.txt are included in other projects/CMakeLists.txt files as a dependency via the add_subdirectory method, for example: add_subdirectory(mozjpeg). There are several reasons and workflows which "wrap" third party projects/builds using this method, including many enterprise build/devops pipelines.

This change will have no effect on users building mozjpeg by itself as usual, it very simply enables the wrapping use cases.
2018-06-07 08:53:21 -04:00
Kornel
f7aeafaf00 Merge pull request #287 from JosePineiro/master
Add -nojfif param
2018-06-05 01:24:09 +01:00
JosePineiro
fce0382181 Add -nojfif param
With this parem do not write JFIF APP0 marker segment. Reduce size in 18 bytes.  This is a mandatory marker, but no error in know programs if are lost. Safe for web use.
2018-06-04 21:06:40 +02:00
DRC
3041cf67ff Travis: Use SKS keyserver pool
pgp.mit.edu seems to be frequently down, which was causing the PR builds
to fail.
2018-05-21 22:52:39 -05:00
DRC
1a85fc497d Additional code formatting tweaks
... detected with an improved version of our checkstyle script
2018-05-21 12:07:40 -05:00
DRC
eb8bba627f Java: Further style refinements
(detected by enabling additional checkstyle modules)

This commit also removes unnecessary uses of the "private" modifier in
the Java tests/examples.  The default access modifier disallows access
outside of the package, and none of these classes is in a package.  The
only reason we use "private" with member variables in these classes is
to make checkstyle happy, because we want it to enforce that behavior in
the TurboJPEG API code.
2018-05-16 11:05:01 -05:00
DRC
53bb941845 Java: Reformat code per checkstyle recommendations
... and modify tjbench.c to match the variable name changes made to
TJBench.java

("checkstyle" = http://checkstyle.sourceforge.net, not our regex-based
checkstyle script)
2018-05-15 14:59:57 -05:00
DRC
2401e4d10c TurboJPEG: Handle CMYK JPEGs w/ subsampled M, Y
Arguably it doesn't make much sense for non-chroma components to be
subsampled (which is why this type of image was overlooked in
cd7c3e6672cce3779450c6dd10d0d70b0c2278b2-- I didn't realize it was a
thing), but certain Adobe applications apparently generate these images.

Fixes #236
2018-04-26 18:15:27 -05:00
DRC
34e9d7e340 Bump revision to 1.5.91 for post-beta fixes 2018-04-26 17:33:52 -05:00
DRC
dc9bdf143a Additional code formatting tweaks
... detected with an improved version of our checkstyle script
2018-04-12 17:02:10 -05:00
DRC
b2d000e64b "Further" = "Furthermore"
Grammar Police.  Has Ray Stevens taught me nothing?
2018-04-11 10:47:16 -05:00
DRC
bfc3ce3157 x86[-64] SIMD: Don't auto-generate jsimdcfg.inc
The old Un*x (autotools-based) build system always auto-generated this
file, but that behavior was more or less a relic of the days before the
libjpeg-turbo colorspace extensions were implemented.  The thinking was
that, if a particular developer wanted to change RGB_RED, RGB_GREEN,
RGB_BLUE, or RGB_PIXELSIZE in order to compress from/decompress to
different RGB pixel layouts, then the SIMD extensions should
automatically respond to those changes whenever they were made to
jmorecfg.h.  The modern reality is that changing RGB_* is no longer
necessary because of the libjpeg-turbo colorspace extensions, and
changing any of the other constants in jsimdcfg.inc can't be done
without making deeper modifications to the SIMD extensions.  In general,
we treat RGB_* as a de facto, immutable part of the legacy libpjeg API.
Realistically, since the values of those constants have been the same in
every Un*x distribution released in the past 20-30 years, any software
that uses a system-supplied build of libjpeg must assume that those
constants will have default values.

Furthermore, even if it made sense to auto-generate jsimdcfg.inc, it was
never possible to do so on Windows, so it was always going to be
necessary to manually generate the Windows version of the file whenever
any of the constants changed.  This commit introduces a new custom CMake
target called "jsimdcfg" that can be used, on Un*x platforms, to
generate jsimdcfg.inc on demand, although this should only be necessary
when introducing new x86 SIMD instructions or making other deep
modifications, such as SIMD acceleration for 12-bit JPEGs.

For those who may be wondering why we don't do the same thing for
win/jconfig.h.in, it's because performing all of the necessary CMake
checks to populate that file is very slow on Windows.
2018-04-10 16:46:47 -05:00
mayeut
269e84c971 jsimd_can_encode_mcu_AC_*(): Remove useless checks
These were necessary for the first iteration of the feature (see #46),
which provided a different C front end for the SIMD version of the
function.  The final version of the feature uses a common C front end
for both SIMD and non-SIMD implementations, so these checks are no
longer necessary.

Closes #231
2018-04-09 21:30:25 -05:00
DRC
b628d6934f Additional code formatting tweaks
... detected with an improved version of our checkstyle script
2018-04-09 10:47:14 -05:00
DRC
450306a84b READMEs: Mention that prog JPEG is now accelerated 2018-04-06 18:31:17 -05:00
DRC
ed3c527386 README.ijg: Wordsmith per ISO/ITU-T suggestions
This commit merges the following paragraph from the latest libjpeg
release:
https://github.com/libjpeg-turbo/ijg/blob/jpeg-9c/README#L222-L229
which takes into account the fact that JFIF is now an official ISO/ITU-T
standard.  I also included the ISO/IEC document number for the JFIF spec
(jpeg-9c included only the ITU-T rec number.)

This commit also heavily wordsmiths the "FILE FORMAT WARS" section.
In jpeg-7 and later, this section has become somewhat impolitic,
referring to JPEG 2000 and JPEG XR as "faulty technologies" and
"momentary mistakes."  The original intent of this section, which was
introduced in jpeg-5 and refined in jpeg-6
(https://github.com/libjpeg-turbo/ijg/blob/jpeg-5/README#L317-L338,
https://github.com/libjpeg-turbo/ijg/blob/jpeg-6b/README#L335-L367)
was to highlight the problem of JPEG file format divergence that existed
in the 1990s prior to the adoption of JFIF as an official ISO/ITU-T
standard.  That problem is fortunately no longer a problem, thanks in
part to the existence of libjpeg.  I have attempted to preserve Tom's
intent of using this section to describe which file formats the code is
compatible with and why it isn't compatible with some file formats
bearing the name "JPEG."  Such modifications always put our project in a
very awkward position, because we are not the IJG and do not claim to
be, but it is still necessary for us to modify the IJG README file from
time to time to eliminate obsolete information while attempting to
remain as neutral as possible.
2018-04-06 18:18:27 -05:00
DRC
4a275cf080 Fix compiler warning w/ 32-bit MSVC builds 2018-03-31 21:49:01 -05:00
DRC
13e4803e6a Fix build errors when C flags include -Werror
Instructing the compiler to treat warnings as errors caused some of the
compiler tests to fail, because the test code was not 100% clean.

Note that we now use check_symbol_exists() to check for memset() and
memcpy(), since the test code for check_function_exists() produces a
compiler warning due to not including <string.h>.
2018-03-31 19:25:12 -05:00
DRC
a74655af45 CMakeLists.txt: Move intrin.h header check
It is more readable for this to be next to the __builtin_ctzl() check,
since both are used by the accelerated progressive Huffman code.
2018-03-31 15:35:08 -05:00
DRC
58cb10ee5f Eliminate compiler warnings w/ Solaris Studio 2018-03-31 14:03:37 -05:00
DRC
7b3c0f0109 PowerPC: Fix comp. warning when built w/ -maltivec 2018-03-31 14:03:02 -05:00
DRC
72964b8633 LICENSE.md: Explain why three licenses were used 2018-03-31 12:46:13 -05:00
DRC
3270768736 jversion.h: Bump copyright year to 2018 2018-03-31 12:46:13 -05:00
DRC
51f94caba1 Build: Use Colin Plumb's public domain MD5 code
... instead of the RSA code, the license for which contains an
advertising clause.  It is strongly believed that the RSA advertising
clause is innocuous, because:

- A clarification from RSA
  (http://www.ietf.org/ietf-ftp/IPR/RSA-MD-all), published in 2000,
  stated:

  "Implementations of these message-digest algorithms, including
  implementations derived from the reference C code in RFC-1319,
  RFC-1320, and RFC-1321, may be made, used, and sold without license
  from RSA for any purpose."

  Referring to the opinion from Fedora's legal team
  (https://fedoraproject.org/wiki/Licensing:FAQ?rd=Licensing/FAQ#What_about_the_RSA_license_on_their_MD5_implementation.3F_Isn.27t_that_GPL-incompatible.3F),
  this means that md5.c and md5.h, which were derived from the original
  RFC 1321 reference code (http://www.faqs.org/rfcs/rfc1321.html), can
  be used without the RSA license.

- In the context of libjpeg-turbo, RSA's MD5 code was used only in the
  build/test system.  It was not part of the libjpeg-turbo binary
  distribution, and thus the only "material mentioning or referencing"
  the MD5 code was the libjpeg-turbo source code, which-- by virtue of
  including RSA's original copyright headers-- properly attributed the
  code as required under the RSA license.

However, in light of the open source community's tendency to have
knee-jerk reactions to stuff like this, it would've been necessary to
include the above explanation in our source tree in order to head off
potential FUD, and a simple fix is always better than a complex
explanation.

This commit also assigns the 3-clause BSD license to my modifications of
the MD5 code.  This license is the same one used by md5cmp and other
parts of the build system.
2018-03-31 12:46:07 -05:00
Matthieu Darbois
9a12cf7ab5 Travis: Deploy only when using official repo
This prevents build failures on forks that contain a master or dev
branch.
2018-03-29 17:33:00 -05:00
DRC
c80ddef7a4 Build: Fix rpath in iOS shared libraries
When attempting to configure an iOS/ARM build with Xcode 7.2 and CMake
2.8.12, I got the following errors:

CMake Error at CMakeLists.txt:560 (add_library):
  Attempting to use MACOSX_RPATH without CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG
  being set.  This could be because you are using a Mac OS X version less
  than 10.5 or because CMake's platform configuration is corrupt.
(x 3)

CMake Error at sharedlib/CMakeLists.txt:38 (add_library):
  Attempting to use MACOSX_RPATH without CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG
  being set.  This could be because you are using a Mac OS X version less
  than 10.5 or because CMake's platform configuration is corrupt.
(x 3)

Upgrading to CMake 3.x (tried 3.0 and 3.1) got rid of the errors, but
the resulting shared libs still did not use @rpath as expected.  Note
also that CMake 3.x (at least the two versions I tested) does not
automatically set the MACOSX_RPATH property as claimed.  I could find
nothing in the release notes for later CMake releases to indicate that
either problem has been fixed.  What I did find was this little nugget
of code in the Darwin platform module:

f6b93fbf3a/Modules/Platform/Darwin.cmake (L33-L36)

This sets CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG="-Wl,-rpath," only if you
are running OS X 10.5 or later.  It makes no such check for iOS, perhaps
because shared libraries aren't much of a thing with iOS apps.  In any
event, this commit simply sets CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG if it
isn't set already, and that fixes all of the aforementioned problems.
2018-03-23 23:45:44 -05:00
DRC
d3a1f899ee Travis: Don't build tags 2018-03-23 16:11:06 -05:00
DRC
d64e8e2905 Fix continuous integration of pull requests
- Travis doesn't set the $encrypted_* variables for PRs, so disable GPG
signing when building a PR (artifacts aren't deployed for PRs anyhow,
and even if they were, I wouldn't want them to be signed, as they may
contain unvetted code.)
- Take advantage of the new -d option in buildljt, which allows for
building from an existing Git clone directory.  This eliminates the need
to rename and restore .git/shallow, allows the official build scripts to
work properly when building PRs, and prevents 'git clone' being invoked
twice in CI builds.

Refer to #217
2018-03-23 14:57:09 -05:00
DRC
e15a6b4e08 Include .pc and man files in MinGW install[er]s
These files are potentially useful to MinGW users, since MSYS2 MinGW
environments have a man command by default and provide an easy way to
install pkg-config.

Closes #223
2018-03-23 11:19:29 -05:00
DRC
ca56642128 release/installer.nsi.in: Remove extraneous quotes
These don't seem to affect anything, because $INSTDIR is already quoted
per 25758055ac.
2018-03-23 11:04:45 -05:00
DRC
3fa69b4d61 jcphuff.c: Fix compiler warning
Misleading indentation, introduced by
5b177b3cab
2018-03-23 10:41:07 -05:00
DRC
d83c997749 README.md: clarify where API docs can be found 2018-03-23 00:00:58 -05:00
DRC
d66dc70d7b ChangeLog.md: bump revision to prepare for beta 2018-03-22 17:16:12 -05:00
DRC
8adf4c0a4f jcphuff.c: Fix compiler warning with Visual C++
GCC doesn't seem to care if we pass no arguments to the ENCODE_COEFS*
macros, but MSVC does.  Insert a no-op to make it happy.
2018-03-22 17:14:15 -05:00
DRC
1095b822b0 Bump revision to 1.5.90 to prepare for beta 2018-03-22 16:08:25 -05:00
DRC
c0ca354eb4 Label this release 2.0 instead of 1.6
This also pulls the formatting changes from
19c791cdac into the TurboJPEG C API docs.
2018-03-22 16:05:58 -05:00
DRC
2e90ccac0b ChangeLog.md: clarification regarding AVX2 2018-03-22 15:56:09 -05:00
mayeut
5b177b3cab C/SSE2 optimization of encode_mcu_AC_first()
This commit adds C and SSE2 optimizations for the encode_mcu_AC_first()
function used in progressive Huffman encoding.

The image used for testing can be retrieved from this page:
https://blog.cloudflare.com/doubling-the-speed-of-jpegtran

All timings done on `Intel(R) Core(TM) i7-4870HQ CPU @ 2.50GHz`
clang version is `Apple LLVM version 9.0.0 (clang-900.0.39.2)`
gcc-5 version is `gcc-5 (Homebrew GCC 5.5.0) 5.5.0`
gcc-7 version is `gcc-7 (Homebrew GCC 7.2.0) 7.2.0`

Here are the results in comparison to libjpeg-turbo@293263c using
`time ./jpegtran -outfile /dev/null -progressive -optimise -copy none print_poster_0025.jpg`

C
clang x86_64: +19%
gcc-5 x86_64: +80%
gcc-7 x86_64: +57%
clang i386: +5%
gcc-5 i386: +59%
gcc-7 i386: +51%

SSE2
clang x86_64: +79%
gcc-5 x86_64: +158%
gcc-7 x86_64: +122%
clang i386: +71%
gcc-5 i386: +134%
gcc-7 i386: +135%

Discussion in libjpeg-turbo/libjpeg-turbo#46
2018-03-22 15:49:23 -05:00
mayeut
16bd984557 C/SSE2 optimization of encode_mcu_AC_refine()
This commit adds C and SSE2 optimizations for the encode_mcu_AC_refine()
function used in progressive Huffman encoding.

The image used for testing can be retrieved from this page:
https://blog.cloudflare.com/doubling-the-speed-of-jpegtran

All timings done on `Intel(R) Core(TM) i7-4870HQ CPU @ 2.50GHz`
clang version is `Apple LLVM version 9.0.0 (clang-900.0.39.2)`
gcc-5 version is `gcc-5 (Homebrew GCC 5.5.0) 5.5.0`
gcc-7 version is `gcc-7 (Homebrew GCC 7.2.0) 7.2.0`

Here are the results in comparison to libjpeg-turbo@3c54642 using
`time ./jpegtran -outfile /dev/null -progressive -optimise -copy none print_poster_0025.jpg`

C
clang x86_64: +7%
gcc-5 x86_64: +30%
gcc-7 x86_64: +33%
clang i386: +0%
gcc-5 i386: +24%
gcc-7 i386: +23%

SSE2
clang x86_64: +42%
gcc-5 x86_64: +53%
gcc-7 x86_64: +64%
clang i386: +35%
gcc-5 i386: +46%
gcc-7 i386: +49%

Discussion in libjpeg-turbo/libjpeg-turbo#46
2018-03-22 13:05:55 -05:00
DRC
81baa1b501 simd/i386/jchuff-sse2.asm: Minor formatting tweak 2018-03-21 13:03:30 -05:00
DRC
293263c352 Format preprocessor macros more consistently
Within the libjpeg API code, it seems to be more the convention than not
to separate the macro name and value by two or more spaces, which
improves general readability.  Making this consistent across all of
libjpeg-turbo is less about my individual preferences and more about
making it easy to automatically detect variations from our chosen
formatting convention.  I intend to release the script I'm using to
validate this stuff, once it matures and stabilizes a bit.
2018-03-17 15:19:41 -05:00
DRC
09497c1a73 Additional code formatting tweaks
Missed by previous analysis
2018-03-17 00:28:17 -05:00
DRC
84fbd4f1ed Merge branch 'master' into dev 2018-03-17 00:27:49 -05:00
DRC
bd96b30b74 Make all get/putenv() calls compile-time optional
* Modify the SIMD dispatchers so they guard their usage of getenv() with
  the existing NO_GETENV preprocessor definition.
* Introduce a new NO_PUTENV preprocessor definition to guard the
  usage of putenv() in the TurboJPEG API library.

This at least puts Windows Store compatibility within the realm of
possibility, although further steps are required.
2018-03-17 00:10:44 -05:00
DRC
25758055ac Win installer: allow install directories w/ spaces 2018-03-16 20:34:18 -05:00
Cameron Cawley
c743009717 Fix build with older MinGW releases
Some MinGW implementations need stdint.h in order to define SIZE_MAX.

Regression caused by a09ba29a55 and
not fully fixed by a0047bdea4.

Closes #220
2018-03-16 19:06:12 -05:00
DRC
29e453f7c0 turbojpeg.c: Fix Windows build
Broken by previous commit.  Although turbojpeg.c no longer needs
tjutil.h on Un*x, it still needs to include that file on Windows in
order to use snprintf() and strcasecmp() (which, on Windows, are macros
that wrap _snprintf_s() and stricmp().)
2018-03-16 14:12:15 -05:00
DRC
a4da0750f0 Merge branch 'master' into dev 2018-03-16 02:16:41 -05:00
DRC
19c791cdac Improve code formatting consistency
With rare exceptions ...
- Always separate line continuation characters by one space from
  preceding code.
- Always use two-space indentation.  Never use tabs.
- Always use K&R-style conditional blocks.
- Always surround operators with spaces, except in raw assembly code.
- Always put a space after, but not before, a comma.
- Never put a space between type casts and variables/function calls.
- Never put a space between the function name and the argument list in
  function declarations and prototypes.
- Always surround braces ('{' and '}') with spaces.
- Always surround statements (if, for, else, catch, while, do, switch)
  with spaces.
- Always attach pointer symbols ('*' and '**') to the variable or
  function name.
- Always precede pointer symbols ('*' and '**') by a space in type
  casts.
- Use the MIN() macro from jpegint.h within the libjpeg and TurboJPEG
  API libraries (using min() from tjutil.h is still necessary for
  TJBench.)
- Where it makes sense (particularly in the TurboJPEG code), put a blank
  line after variable declaration blocks.
- Always separate statements in one-liners by two spaces.

The purpose of this was to ease maintenance on my part and also to make
it easier for contributors to figure out how to format patch
submissions.  This was admittedly confusing (even to me sometimes) when
we had 3 or 4 different style conventions in the same source tree.  The
new convention is more consistent with the formatting of other OSS code
bases.

This commit corrects deviations from the chosen formatting style in the
libjpeg API code and reformats the TurboJPEG API code such that it
conforms to the same standard.

NOTES:
- Although it is no longer necessary for the function name in function
  declarations to begin in Column 1 (this was historically necessary
  because of the ansi2knr utility, which allowed libjpeg to be built
  with non-ANSI compilers), we retain that formatting for the libjpeg
  code because it improves readability when using libjpeg's function
  attribute macros (GLOBAL(), etc.)
- This reformatting project was accomplished with the help of AStyle and
  Uncrustify, although neither was completely up to the task, and thus
  a great deal of manual tweaking was required.  Note to developers of
  code formatting utilities:  the libjpeg-turbo code base is an
  excellent test bed, because AFAICT, it breaks every single one of the
  utilities that are currently available.
- The legacy (MMX, SSE, 3DNow!) assembly code for i386 has been
  formatted to match the SSE2 code (refer to
  ff5685d5344273df321eb63a005eaae19d2496e3.)  I hadn't intended to
  bother with this, but the Loongson MMI implementation demonstrated
  that there is still academic value to the MMX implementation, as an
  algorithmic model for other 64-bit vector implementations.  Thus, it
  is desirable to improve its readability in the same manner as that of
  the SSE2 implementation.
2018-03-16 02:14:34 -05:00
DRC
d45434fe19 usage.txt: Remove Alt-Space non-ASCII character 2018-03-16 02:13:03 -05:00
Kornel
b85de60a9f Merge pull request #280 from vvuk/master
Add optional PNG support to CMake build
2018-03-14 00:14:18 +00:00
Vladimir Vukicevic
e73ee60a8f Add optional PNG support to CMake build 2018-03-13 16:58:33 -07:00
DRC
4508ab3e51 Fix build when RGB_{RED,GREEN,BLUE}!={0,1,2}
Broken by aa7459050d
2018-03-13 10:57:08 -05:00
DRC
87bc8721b4 Travis: OS X official builds now use YASM
Because 367a838626
2018-03-05 12:50:48 -06:00
DRC
33ce0b5e71 Loongson MMI SIMD extensions
Based on:
42aff4497b

Closes #158
2018-03-05 12:16:11 -06:00
DRC
35ed3c97b2 SIMD: Formatting tweaks + remove unnecessary code
+ "JSIMD_ARM_NEON" = "JSIMD_NEON"
+ "JSIMD_MIPS_DSPR2" = "JSIMD_DSPR2"
+ "*_mips_dspr2" = "*_dspr2"

It's obvious that "NEON" refers to Arm and "DSPr2" refers to MIPS, and
this naming convention is consistent with the other SIMD extensions.
2018-03-01 18:53:58 -06:00
DRC
3c54642c81 Fix iOS/ARM[-64] build w/ newer versions of CMake
Newer versions of CMake (known to be the case with 3.7.x and 3.10.x)
fail to add a space between CMAKE_C_FLAGS and CMAKE_ASM_FLAGS, which
causes the build to fail when using the official build procedure.

Closes #216
2018-02-27 11:40:05 -06:00
DRC
367a838626 Make SIMD syms private for x86[-64]/Mach-O builds
... if building with YASM.  NASM doesn't currently support the necessary
directives.

Closes #212
2018-02-26 21:02:55 -06:00
DRC
7c2bfdb040 Merge branch 'master' into dev
Closes #214
2018-02-26 18:43:40 -06:00
mayeut
0dd9a2c1fd Fix Win64 ABI conformance when using xmm8-xmm11
Referring to https://docs.microsoft.com/en-US/cpp/build/stack-usage:

"All memory beyond the current address of RSP is considered volatile:
The OS, or a debugger, may overwrite this memory during a user debug
session, or an interrupt handler.  Thus, RSP must always be set before
attempting to read or write values to a stack frame."

Basically, if-- under extremely rare circumstances-- a context swap were
to occur between saving the values of xmm8-xmm11 and setting the new
value of rsp, the O/S might not preserve that area of the stack.  In
general, libjpeg-turbo should not be using xmm8-xmm11 before or after
the call to jsimd_huff_encode_one_block_sse2(), so this is probably a
non-issue, but it's still a good idea to fix it.

Based on
ff7d2030dd
2018-02-26 18:00:15 -06:00
Matthieu Darbois
32eaeeac9e Fix BUILDING.md buglet ("--mfloat-abi=softfp")
(Introduced with the build system overhaul)

Closes #215
2018-02-26 12:56:31 -06:00
mayeut
4c4dc6149b Fix Win64 ABI conformance issue in AVX2 ISLOW IDCT
xmm8-xmm11 must be saved and restored, since the function uses
ymm8-ymm11.

Closes #211
2018-02-26 12:00:56 -06:00
mayeut
feaec37d32 Fix build with YASM
vinserti128 requires all operands to be specified
2018-02-24 16:50:03 -06:00
mayeut
b6909ab3f7 Make SIMD symbols private for MIPS ELF builds
Closes #210
2018-02-23 18:49:08 -06:00
mayeut
9bef5df776 Make SIMD symbols private for iOS ARM/ARM64 builds 2018-02-23 18:39:06 -06:00
mayeut
88421563ad Make SIMD symbols private for x86[-64] ELF builds 2018-02-23 18:37:46 -06:00
DRC
9cdec16ceb 32-bit AVX2 implementation of slow int inverse DCT 2018-02-23 15:19:16 -06:00
DRC
845fe8bf80 32-bit AVX2 buglet: IS_ALIGNED_SSE=IS_ALIGNED_AVX 2018-02-23 12:24:10 -06:00
DRC
de9e9db6a5 64-bit AVX2 implementation of slow int inverse DCT 2018-02-23 11:50:11 -06:00
DRC
715b7c38a8 32-bit AVX2 implementation of int sample conv. 2018-02-19 00:24:53 -06:00
DRC
ca387e7fda 32-bit AVX2 implementation of slow int forward DCT 2018-02-19 00:00:55 -06:00
DRC
39e9e65c5b 64-bit AVX2 implementation of int sample conv. 2018-02-18 23:30:14 -06:00
DRC
264dd42a98 64-bit AVX2 implementation of slow int forward DCT 2018-02-18 23:30:08 -06:00
DRC
ff392d81ef AVX2: Introduce YMMBLOCK macro for readability 2018-02-17 17:29:38 -06:00
DRC
37bae1a0e9 Prog Huff enc: bit count/branchless abs val opts
Ported from baseline Huffman encoder.  This improves overall compression
performance by ~3-9% in my testing.
2018-02-14 17:24:08 -06:00
DRC
985ef4f9f1 Merge branch 'master' into dev 2018-02-14 14:50:04 -06:00
Ben Boeckel
700de8aa81 README.md: Fix permissions 2018-02-14 14:41:36 -06:00
DRC
4e240795cc Merge branch 'master' into dev 2018-02-13 16:34:21 -06:00
DRC
d4859558da Fix dithering bug in merged 4:2:0/RGB565 algorithm
d0 should always be used for the first row, and d1 should always be used
for the second row.

Addresses concerns raised in #95, #81.
2018-02-13 16:22:43 -06:00
DRC
289014d470 Merge branch 'master' into dev 2018-01-05 12:05:43 -06:00
Stephen
3847f91122 Travis/OS X: Use 'brew bundle' + Brewfile
This ensures that the build script will not fail if the Homebrew
dependencies are already installed.
2018-01-03 09:57:21 -08:00
Kornel
f918646f9a Merge pull request #276 from mozilla/merge-1.5.3
Merge libjpeg-turbo 1.5.3
2017-12-29 20:34:31 +00:00
Kornel
365bc1ce11 Make IDCT method customizable 2017-12-23 01:29:16 +00:00
Kornel
836e711c38 Merge tag '1.5.3'
Tag 1.5.3 release

* tag '1.5.3': (29 commits)
  Fix whitespace errors
  jpeg_crop_scanlines: Handle gray images w/ samp!=1
  Fix lib state when skipping to end of 1-scan image
  Travis: Work around xcode7.3 image bug
  TJExample: Fix array index OOB w/ 4:1:1 JPEG input
  Code formatting tweaks
  Uniquify tjbenchtest log file names based on args
  TJExample.java: Don't ignore mistyped args
  Doc tweak: TJFLAG_ACCURATEDCT is the first flag
  tjbench.exe: Fix decompression access violation
  ChangeLog.md: buglet
  Build: Fix `make dist`
  Further partial image decompression fixes
  TJBench/TJUnitTest: Don't ignore mistyped args
  TurboJPEG C: Code formatting tweaks
  djpeg -crop: Exit gracefully with non-PPM formats
  Prevent "unmappable character" error in Java build
  Fix PowerPC 32-bit RPM build
  Fix 32-bit RPM build w/ newer RHEL/Fedora releases
  Packaging: Use parallel make when rebuilding SRPM
  ...
2017-12-23 01:10:55 +00:00
DRC
bd544e284b Merge branch 'master' into dev 2017-12-16 09:34:28 -06:00
DRC
0e2bca0744 jdarith.c: Fix two signed integer overflows
I guess I have to fix these, or Google Autofuzz is going to keep bugging
me about them.

Fixes #171
Fixes #197
Fixes #198
2017-12-15 20:37:02 -06:00
DRC
0fba3c1993 Bump version to 1.5.4 to prepare for new commits 2017-12-15 20:05:58 -06:00
DRC
7d3feda796 BUILDING.md: Adjust Android recipes for NDK r16+
NDK r16b moved some things around, so modify the Android build recipes
to take that into account while preserving compatibility with previous
NDK releases.

NOTE: the GCC 4.9 NDK toolchain is deprecated, so we will need to
develop new Android build recipes for libjpeg-turbo 1.6 that use the
Clang toolchain.

Closes #196
2017-12-15 16:53:25 -06:00
DRC
bf6c774305 Fix whitespace errors 2017-12-13 21:48:54 -06:00
DRC
afdd7999e4 Merge branch 'master' into dev
+ acknowledge 1.5.3 release
2017-12-06 12:20:24 -06:00
DRC
c308d43416 jpeg_crop_scanlines: Handle gray images w/ samp!=1
Since the sampling factor has no meaning for single-component images,
the decompressor ignores it, and jpeg_crop_scanlines() should as well.

Fixes #195
2017-12-06 11:59:04 -06:00
DRC
773040f9d9 Fix lib state when skipping to end of 1-scan image
If jpeg_skip_scanlines() is used to skip to the end of a single-scan
image, then we need to change the library state such that subsequent
calls to jpeg_consume_input() will return JPEG_REACHED_EOI rather than
JPEG_SUSPENDED.  (NOTE: not necessary for multi-scan images, since the
scans are processed prior to any call to jpeg_skip_scanlines().)

Unless I miss my guess, using jpeg_skip_scanlines() in this manner
will prevent any markers at the end of the JPEG image from being
read, but I don't think there is any way around that without actually
reading the data, which would defeat the purpose of
jpeg_skip_scanlines().

Fixes #194
2017-12-05 16:08:01 -06:00
DRC
c05d124968 Merge branch 'master' into dev 2017-11-29 14:36:39 -06:00
DRC
a831b5a986 Travis: Work around xcode7.3 image bug
Refer to travis-ci/travis-ci#8552.  This was supposed to be fixed on
November 15, then on November 28.  Travis blew through both deadlines,
so I have no confidence that the issue will be fixed as promised in a
timely manner.  Adding 'brew update' to .travis.yml slows the OS X
build, but there is no choice at the moment.
2017-11-29 14:23:31 -06:00
DRC
9f1f86bf7f tjLoadImage(): Fix OOB array access w/TJPF_UNKNOWN
Because the previous commit added a test for TJPF_UNKNOWN to tjunittest,
the ASAN CI build detected this issue.
2017-11-19 09:21:37 -06:00
DRC
e817c07779 tjLoadImage(): return TJPF_GRAY for grayscale BMPs
... if *pixelFormat=TJPF_UNKNOWN is passed to the function.
2017-11-19 08:43:07 -06:00
DRC
479fa1d870 tjLoadImage(): Don't convert RGB to grayscale
Loading RGB image files into a grayscale buffer isn't a particularly
useful feature, given that libjpeg-turbo can perform this conversion
much more optimally (with SIMD acceleration on some platforms) during
the compression process.  Also, the RGB2GRAY() macro was not producing
deterministic cross-platform results because of variations in the
round-off behavior of various floating point implementations, so
`tjunittest -bmp` was failing in i386 builds.
2017-11-18 11:40:53 -06:00
DRC
8c40ac8ae6 Add TurboJPEG C example and clean up Java example
Also rename example.c --> example.txt and add a disclaimer to that file
so people will stop trying to compile it.
2017-11-17 22:49:11 -06:00
DRC
dc4b900223 TurboJPEG: Add alpha offset array/method
Also, set the red/green/blue offsets for TJPF_GRAY to -1 rather than 0.
It was undefined behavior for an application to use those arrays/methods
with TJPF_GRAY anyhow, and this makes it easier for applications to
programmatically detect whether a given pixel format has red, green, and
blue components.
2017-11-17 22:49:07 -06:00
DRC
aa7459050d TurboJPEG C API: Add BMP/PPM load/save functions
The main justification for this is to provide new libjpeg-turbo users
with a quick & easy way of developing a complete JPEG
compression/decompression program without requiring them to build
libjpeg-turbo from source (which was necessary in order to use the
project-private bmp API) or to use external libraries.  These new
functions build upon significant enhancements to rdbmp.c, wrbmp.c,
rdppm.c, and wrppm.c which allow those engines to convert directly
between the native pixel format of the file and a pixel format
("colorspace" in libjpeg parlance) specified by the calling program.
rdbmp.c and wrbmp.c have also been modified such that the calling
program can choose to read or write image rows in the native (bottom-up)
order of the file format, thus eliminating the need to use an inversion
array.  tjLoadImage() and tjSaveImage() leverage these new underlying
features in order to significantly improve upon the performance of the
old bmp API.

Because these new functions cannot work without the libjpeg-turbo
colorspace extensions, the libjpeg-compatible code in turbojpeg.c has
been removed.  That code was only there to serve as an example of how
to use the TurboJPEG API on top of libjpeg, but more specific, buildable
examples now exist in the https://github.com/libjpeg-turbo/ijg
repository.
2017-11-17 19:32:52 -06:00
DRC
087ec126c1 tjbenchtest: Test new TurboJPEG progressive flag 2017-11-17 19:31:32 -06:00
DRC
cd8a12586a Build: Fix 'tjtest' target on Windows
tjbenchtest and its Java derivatives are useful for rooting out hidden
problems with the more esoteric TJBench and TurboJPEG features.  For
instance, on Windows, running tjbenchtest uncovered
5fce2e9421.

This commit also causes tjbenchtest and tjbenchtest.java to append -yuv
and -alloc to their log file names, depending on the arguments passed,
and it causes the build system to clean up those log files when the
'testclean' target is built.
2017-11-17 19:11:07 -06:00
DRC
4893e5d8b8 Merge branch 'master' into dev 2017-11-17 19:00:53 -06:00
DRC
19b393b624 TJExample: Fix array index OOB w/ 4:1:1 JPEG input 2017-11-17 18:45:08 -06:00
DRC
9d9d8fe658 Code formatting tweaks 2017-11-17 18:39:53 -06:00
DRC
78e97e38cb Uniquify tjbenchtest log file names based on args
+ clean up log files when 'make testclean' is invoked
+ fix 'tjbenchtest -yuv -alloc'
+ fix tjexampletest so that it creates images under /tmp
+ clean up tjexampletest
2017-11-17 18:39:53 -06:00
DRC
468f2fed27 TJExample.java: Don't ignore mistyped args 2017-11-17 18:39:48 -06:00
DRC
5abf2536f6 Doc tweak: TJFLAG_ACCURATEDCT is the first flag 2017-11-14 16:12:13 -06:00
DRC
5fce2e9421 tjbench.exe: Fix decompression access violation
The program crashed when a JPEG image was passed on the command line,
because we were mixing our metaphors vis-a-vis malloc()/free() and
tjAlloc()/tjFree() (malloc()/free() uses the tjbench.exe heap,
whereas tjAlloc()/tjFree() uses the turbojpeg.dll heap.)
2017-11-14 15:41:30 -06:00
DRC
907dd683a4 ChangeLog.md: buglet 2017-11-13 21:46:07 -06:00
DRC
f008876cc1 Build: Fix make dist
Broken by previous commit
2017-11-13 21:24:05 -06:00
DRC
5bc43c7821 Further partial image decompression fixes
- Referring to 073b0e88a1 and #185, the
  reason why BMP and RLE didn't (and won't) work with partial image
  decompression is that the output engines for both formats maintain a
  whole-image buffer, which is used to reverse the order of scanlines.
  However, it was straightforward to add -crop support for GIF and
  Targa, which is useful for testing partial image decompression along
  with color quantization.
- Such testing reproduced a bug reported by Mozilla (refer to PR #182)
  whereby jpeg_skip_scanlines() would segfault if color quantization was
  enabled.  To fix this issue, read_and_discard_scanlines() now sets up
  a dummy quantize function in the same manner that it sets up a dummy
  color conversion function.

Closes #182
2017-11-13 21:01:53 -06:00
DRC
f3ad13e3d8 TJBench/TJUnitTest: Don't ignore mistyped args 2017-11-13 16:00:35 -06:00
DRC
94e152b186 TurboJPEG C: Code formatting tweaks 2017-11-13 15:14:12 -06:00
DRC
073b0e88a1 djpeg -crop: Exit gracefully with non-PPM formats
... and document that only PPM/PGM output images are supported with the
-crop option for the moment.

I investigated the possibility of supporting -crop with -bmp, but even
after resetting the buffer dimensions, I still kept getting virtual
array access errors.  It seems that doing this the "right way" would
require creating a re-initialization function for each image format's
destination manager.  I'm disinclined to do that right now, given that
this feature was Google's baby (developed as a prerequisite for
including libjpeg-turbo in Android), and the -crop option in djpeg is
intended only as an example of how to use the partial image
decompression API.  Real-world applications would need to handle this
in their own destination managers.

It would probably be possible to make this work with Targa by employing
a similar hack to the one we used with PPM, but Targa isn't popular
enough to bother.

Fixes #185
2017-11-08 21:30:19 -06:00
DRC
616b4e2d1b TurboJPEG C: Compiler warnings
Introduced in b9ab64d8db.
2017-09-20 19:59:21 +00:00
DRC
3d72522a68 SRPM build: Define _libdir based on build arch
Setting _libdir to CMAKE_INSTALL_FULL_LIBDIR only works when doing an
in-tree RPM build.  SRPMs are architecture-agnostic, so the spec needs
to compute_libdir at the time the SRPM is rebuilt, not at the time it
is generated.

This is a regression introduced when implementing the new CMake-based
cross-platform build system.
2017-09-20 18:13:23 +00:00
DRC
f0dd80f246 Merge branch 'master' into dev 2017-09-20 17:13:46 +00:00
DRC
1b385f37f3 Prevent "unmappable character" error in Java build
This was causing the build to fail when rebuilding libjpeg-turbo from
a source RPM.
2017-09-20 17:05:15 +00:00
DRC
fd778bba46 Fix PowerPC 32-bit RPM build 2017-09-20 16:43:27 +00:00
DRC
8d403aeb6a Fix 32-bit RPM build w/ newer RHEL/Fedora releases
The version of RPM on RHEL 5 and older platforms defines _libdir
as %{_exec_prefix}/%{_lib}, so defining _lib in the spec file redefined
_libdir.  However, newer versions of RPM (probably >= 4.6, since that
was the version that introduced the ISA macros) define _libdir as either
%{_prefix}/lib or %{_prefix}/lib64.  Thus, we need to explicitly
override _libdir in our spec file.
2017-09-19 23:15:46 +00:00
DRC
01b74c101e Packaging: Use parallel make when rebuilding SRPM 2017-09-11 10:06:22 -05:00
DRC
db0dec3c5a Travis: Limit parallel make jobs to # of CPU cores
This tends to be faster than 'make -j', since it is making more wise
use of the available resources.
2017-09-11 09:48:33 -05:00
nyg
ba6e9d8a11 wrjpgcom: Fix comment typo
Comment was copied/pasted from skip_variable() without making the
necessary modifications.
2017-09-05 11:23:56 -05:00
DRC
7106ffe5f2 Merge branch 'master' into dev 2017-09-02 04:20:40 +00:00
DRC
5426a4cb16 TJUnitTest: Usage formatting tweaks 2017-09-02 04:08:06 +00:00
DRC
d0bac69a8a Java: Fix TJUnitTest on big endian platforms
It is necessary for the C code to be aware of the machine's endianness,
which is why the TurboJPEG Java wrapper sets a different pixel format
for integer BufferedImages depending on ByteOrder.nativeOrder().
However, it isn't necessary to handle endianness in pure Java code such
as TJUnitTest (d'oh!)  This was a product of porting the C version of
TJUnitTest too literally, and of insufficient testing (historically,
the big endian systems I had available for testing didn't have Java.)
2017-09-02 03:47:56 +00:00
DRC
59322e0973 Build: Change ppc64le DEB arch to ppc64el
This is the convention among Debian-based distros.
2017-09-01 21:57:48 +00:00
DRC
51cc89fa7b Merge branch 'master' into dev 2017-09-01 09:02:55 -05:00
DRC
4ded4dfac6 Build: Fix AltiVec detection on OS X Leopard
The ability to directly access elements of an AltiVec vector is
apparently a more recent thing.
2017-09-01 09:01:00 -05:00
DRC
1d93541617 Build: Use -maltivec when testing AltiVec support
Doesn't seem to be necessary with recent Linux/GCC configurations, but
it is definitely necessary with OS X.
2017-09-01 08:55:33 -05:00
DRC
c0f3512d5a Merge branch 'master' into dev 2017-09-01 07:12:51 -05:00
DRC
02fa8f244e Fix build on PowerPC SPE systems
SPE systems don't support AltiVec instructions.

Fixes #172
2017-08-31 20:32:48 -05:00
DRC
32120054c2 Java: Fix NullPointerException in YUVImage
planes == null is a valid argument to setBuf() if alloc == true, so we
need to make sure that planes is non-null before validating its length.
We also need to allocate one dimension of the planes array if it's null.

Fixes #168
2017-08-14 11:46:26 -05:00
DRC
1478361204 Bump version to 1.5.3 to prepare for new commits 2017-08-14 11:20:19 -05:00
Kornel
f154ccc091 Version bump 2017-07-10 11:58:14 +01:00
Kornel
9be7a47841 Merge tag '1.5.2'
Tag 1.5.2 release

* tag '1.5.2': (54 commits)
  x86: Fix "short jump is out of range" w/ NASM<2.04
  TurboJPEG: Document xform issue w/ big marker data
  Java TJBench: Fix parsing of -warmup argument
  Build: Disable warmup in TJBench regression tests
  TJBench: Improve consistency of results
  TurboJPEG: C API documentation buglet
  TJBench: Code formatting tweaks
  TJBench: Fix errors when decomp. files w/ ICC data
  BUILDING.md: Include Android/x86 build recipes
  Travis: Fix OS X build
  Restore compatibility with older autoconf releases
  Attribute ARM runtime detection code to Nokia
  Honor max_memory_to_use/JPEGMEM/-maxmemory
  AppVeyor: Fix CI build
  TurboJPEG: Fix potential memory leaks
  Always tweak EXIF w/h tags w/ lossless transforms
  Fix error w/ lossless crop & libjpeg v7 emulation
  Include jpeg_skip/crop_scanlines() in jpeg7.dll
  libjpeg.txt: Include partial decomp. in TOC
  Slightly de-confusify cjpeg, jpegtran usage info
  ...
2017-07-10 11:54:52 +01:00
DRC
e5c1613ccd x86: Fix "short jump is out of range" w/ NASM<2.04 2017-07-07 15:28:49 -05:00
Kornel
4d77515bc9 Merge pull request #263 from lambdapioneer/fix_dcscanopt2
Calculate jpeg_simple_progression nscans correctly
2017-07-06 12:21:29 +01:00
Daniel Hugenroth
fb27709ab1 Calculate jpeg_simple_progression nscans correctly 2017-07-06 11:18:19 +01:00
DRC
c94531212f TJBench: Recover from non-fatal errors if possible
Previously, -stoponwarning only had an effect on the underlying
TurboJPEG C functions, but TJBench still aborted if a non-fatal error
occurred.  This commit modifies the C version of TJBench such that it
always recovers from a non-fatal error unless -stoponwarning is
specified.  Furthermore, the benchmark stores the details of the last
non-fatal error and does not print any subsequent non-fatal error
messages unless they differ from the last one.

Due to limitations in the Java API (specifically, the fact that it
cannot communicate errors, fatal or otherwise, to the calling program
without throwing a TJException), it was only possible to make
decompression operations fully recoverable within TJBench.  With other
operations, -stoponwarning still has an effect on the underlying C
library but has no effect at the Java level.

The Java API documentation has been amended to reflect that only certain
methods are truly recoverable, regardless of the state of
TJ.FLAG_STOPONWARNING.
2017-06-29 17:09:53 -05:00
DRC
9baef107e1 TurboJPEG: Don't make STOPONWARNING persistent
Due to an oversight in d4092f6b4d,
the state of TJFLAG_STOPONWARNING persisted beyond the function it
was passed to.
2017-06-29 12:08:02 -05:00
DRC
dadebcd79a TurboJPEG: Add "copy none", progressive xform opts
Allow progressive entropy coding to be enabled on a
transform-by-transform basis, and implement a new transform option for
disabling the copying of markers.

Closes #153
2017-06-28 15:32:33 -05:00
DRC
dedce66eb5 Merge branch 'master' into dev 2017-06-28 15:30:41 -05:00
DRC
b0971e47d7 TurboJPEG: Document xform issue w/ big marker data
If the source image for a transform operation has a lot of EXIF or ICC
data embedded in it, then it may cause the output image size to exceed
the worst-case size returned by tjBufSize() (because tjTransform()
transfers all markers to the output image.)  This is only a problem if
TJFLAG_NOREALLOC is passed to the function.  Since the TurboJPEG C API
doesn't require the destination image size to be set in this case, it
makes the documented assumption that the calling program has allocated
the destination buffer to exactly the size returned by tjBufSize().
Changing this assumption would change the API behavior and necessitate
a new function name (tjTransform2().)  At the moment, it's easier to
just document this as a known issue, since it's easy to work around in
the C API.

The Java API is unfortunately a different story, since it must always
use TJFLAG_NOREALLOC (because, when using the TurboJPEG Java API, all
buffers are allocated on the Java heap, and thus they can't be
reallocated by the C code.)  There is no easy way to work around this
without changing the C API as discussed above, because if the source
image contains large amounts of marker data, it's virtually impossible
to determine how big the output image will be.
2017-06-28 15:22:33 -05:00
DRC
e248d430e2 Java TJBench: Fix parsing of -warmup argument
Due to an oversight, this wasn't included in
1db1ce45da.
2017-06-28 15:22:32 -05:00
DRC
acb634931a Build: Disable warmup in TJBench regression tests
Fixes slow-down in 'make test' caused by previous commit.
2017-06-28 15:19:53 -05:00
DRC
1db1ce45da TJBench: Improve consistency of results
Given that libjpeg-turbo can often process hundreds of megapixels/second
on modern hardware, the default of one warmup iteration was essentially
meaningless.  Furthermore, the -warmup option was a bit clunky, since
it required some foreknowledge of how fast the benchmarks were going to
execute.

This commit introduces a 1-second warmup interval for each benchmark by
default, and the -warmup option has been retasked to control the length
of that interval.
2017-06-27 14:28:43 -05:00
DRC
aba6ae5950 TurboJPEG: Opt. enable progressive entropy coding
Fulfills part of the feature request in #153.  Also paves the way for
SIMD-accelerated progressive Huffman coding (refer to #46.)
2017-06-27 13:26:26 -05:00
DRC
596e3965e7 Merge branch 'master' into dev 2017-06-27 11:51:34 -05:00
DRC
d0c3aa900b TurboJPEG: C API documentation buglet
TJFLAG_NOREALLOC, tjAlloc(), and tjFree() apply to all TurboJPEG
compression functions, not just tjCompress2().
2017-06-27 11:49:38 -05:00
DRC
d4092f6b4d TurboJPEG: Improve error handling
- Provide a new C API function and TJException method that allows
  calling programs to query the severity of a compression/decompression/
  transform error.
- Provide a new flag that instructs the library to immediately stop
  compressing/decompressing/transforming if a warning is encountered.

Fixes #151
2017-06-27 11:03:26 -05:00
DRC
42e1e2d886 Build: Custom target for generating JNI headers 2017-06-27 11:03:26 -05:00
DRC
25c912c1b2 Build: Add custom target for generating Java docs 2017-06-27 11:03:26 -05:00
DRC
178796e748 Build: Fix buglet in java/CMakeLists.txt (MSYS)
CMAKE_HOST_SYSTEM_NAME should be restored with the value of
CMAKE_HOST_SYSTEM_NAME_BAK.
2017-06-27 11:03:26 -05:00
DRC
b9ab64d8db TurboJPEG: Thread-safe error message retrieval
Introduce a new C API function (tjGetErrorStr2()) that can be used to
retrieve compression/decompression/transform error messages in a
thread-safe (i.e. instance-specific) manner.  Retrieving error messages
from global functions is still thread-unsafe.

Addresses a concern expressed in #151.
2017-06-27 10:58:36 -05:00
DRC
2ac4e9d914 Merge branch 'master' into dev 2017-06-26 22:03:32 -05:00
DRC
6a2b067428 TJBench: Code formatting tweaks
Spaces-->tab + remove stray control character that was introduced in
95e4cb2060
2017-06-26 21:15:15 -05:00
DRC
11eec4a398 TJBench: Fix errors when decomp. files w/ ICC data
Embedded ICC profiles can cause the size of a JPEG file to exceed the
size returned by tjBufSize() (which is really meant to be used for
compression anyhow, not for decompression), and this was causing a
segfault (C) or an ArrayIndexOutOfBoundsException (Java) when
decompressing such files with TJBench.  This commit modifies the
benchmark such that, when tiled decompression is disabled, it re-uses
the source buffer as the primary JPEG buffer.
2017-06-26 21:12:40 -05:00
DRC
301ba4f305 BUILDING.md: Include Android/x86 build recipes
Addresses a concern raised in #155.
2017-06-26 21:12:33 -05:00
Kornel
a9bfef2a57 Reset scans to value expected by the TJ API
Fixes #260
2017-05-25 16:32:23 +01:00
Kornel
12909e6a0f Merge pull request #258 from pornel/turbo151
Update to libjpeg-turbo 1.5.1
2017-05-25 16:30:09 +01:00
Kornel
60a61a34fc Ignore test temp files 2017-05-25 16:28:56 +01:00
Kornel
216ccd6702 Merge pull request #259 from pornel/pngtiny
Embed an sRGB profile if PNG had an sRGB chunk
2017-05-21 22:35:31 +01:00
Kornel
88e99ac246 Embed an sRGB profile if PNG had an sRGB chunk 2017-05-11 13:56:06 +01:00
DRC
70f236ddd7 Travis: Fix OS X build
The Travis xcode7.3 image now apparently includes GnuPG 1.4.x by
default, so use it instead of installing GnuPG 2.  Using GnuPG 2.1.x,
the default version in Homebrew as of this writing, is problematic for
this reason:
https://wiki.archlinux.org/index.php/GnuPG#Unattended_passphrase
2017-05-08 14:42:52 -05:00
DRC
2a4f189444 Restore compatibility with older autoconf releases
(broken by f06cc1200f)

Fixes #149
2017-05-05 20:45:40 -05:00
Kornel
78e3171864 Merge pull request #254 from pornel/pngicc
Preserve ICC profile when converting from PNG
2017-05-01 15:26:05 +01:00
Kornel
72d249b89c Merge pull request #253 from pornel/master
Expanded readme
2017-05-01 13:36:38 +01:00
Kornel
075a1e1afc Copy ICC profile from PNG to JPEG 2017-04-30 15:02:57 +01:00
Kornel
2dd5ae7b83 Support G+A PNG (without alpha of course) 2017-04-30 15:02:57 +01:00
Kornel
e95be67503 Prevent overflows in large PNGs 2017-04-30 15:02:57 +01:00
Kornel
ec4255bb74 Expanded readme 2017-04-30 14:06:30 +01:00
DRC
9d64f3c60b Attribute ARM runtime detection code to Nokia
This code was submitted in the initial ARM NEON patches
(https://sourceforge.net/p/libjpeg-turbo/patches/7/) by Siarhei while he
was still a Nokia employee.
2017-04-24 14:42:58 -05:00
Kornel
cfff992fc6 Merge pull request #251 from lambdapioneer/fix_dcscanopt
Calculate jpeg_simple_progression nscans correctly when dc_scan_opt_mode
2017-04-24 10:56:12 +01:00
Daniel Hugenroth
31d957d25a Calculate jpeg_simple_progression nscans correctly with respect to dc_scan_opt_mode 2017-04-21 17:23:50 +01:00
Kornel
41dd774c1f Merge pull request #243 from pornel/autosample
Guess default chroma subsampling setting from the quality setting
2017-04-14 21:29:02 +02:00
Kornel Lesiński
1374cdfabe JPEG_C_PARAM_SUPPORTED to allow detection of the API
Fixes #165
2017-03-18 23:17:47 +00:00
DRC
da2a27ef05 Honor max_memory_to_use/JPEGMEM/-maxmemory
This re-introduces a feature of the obsolete system-specific libjpeg
memory managers-- namely the ability to limit the amount of main memory
used by the library during decompression or multi-pass compression.
This is mainly beneficial for two reasons:

- Works around a 2 GB limit in libFuzzer
- Allows security-sensitive applications to set a memory limit for the
  JPEG decoder so as to work around the progressive JPEG exploit
  (LJT-01-004) described here:
  http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf

This commit also removes obsolete documentation regarding the MS-DOS
memory manager (which itself was removed long ago) and changes the
documentation of the -maxmemory switch and JPEGMEM environment variable
to reflect the fact that backing stores are never used in libjpeg-turbo.

Inspired by:
066fee2e7d

Closes #143
2017-03-18 17:42:34 -05:00
DRC
c082dc039d AppVeyor: Fix CI build
Something changed in the CI build environment, and our previous trick of
setting the Git URL to file://c:/projects/libjpeg-turbo no longer works.
Using cygpath to translate the Windows path to a MinGW-friendly format
is a better solution anyhow.
2017-03-18 13:25:30 -05:00
DRC
d4c41fe0da TurboJPEG: Fix potential memory leaks
Referring to https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=746,
it seems that the values of local buffer pointers in TurboJPEG API
functions aren't always preserved if longjmp() returns control to a
point prior to the allocation of the local buffers.  This is known to
be an issue with GCC 4.x and clang with -O1 and higher optimization
levels but not with GCC 5.x and later.  It is unknown why GCC 5.x and
6.x do not suffer from the issue, but possibly the local buffer pointers
are not allocated on the stack when using those more recent compilers.

In any case, this commit modifies the TurboJPEG API library code such
that the jump buffer is always updated after any local buffer pointers
are allocated but before any subsequent libjpeg API functions are
called.
2017-03-18 13:12:17 -05:00
Kornel Lesiński
3a86fa5b22 If there is no explicit subsample argument, guess the default from the quality setting 2017-03-18 15:33:11 +00:00
Kornel Lesiński
499bd1da89 Merge tag '1.5.1'
Tag 1.5.1 release

* tag '1.5.1':
  ARM64 NEON: Fix another ABI conformance issue
  Build: Remove ARMv6 support from 'make iosdmg'
  Fix out-of-bounds write in partial decomp. feature
  Silence additional UBSan warnings
  Fix unsigned int overflow in libjpeg memory mgr.
  TurboJPEG: Decomp. 4:2:2/4:4:0 JPEGs w/unusual SFs
  Silence pedantic GCC6 code formatting warnings
  Use plain upsampling if merged isn't accelerated
  Implement h1v2 fancy upsampling
  Fix AArch64 ABI conformance issue in SIMD code
  Don't install libturbojpeg.pc if TJPEG disabled
  Linux/PPC: Only enable AltiVec if CPU supports it
  ARM/MIPS: Change the behavior of JSIMD_FORCE*
  Bump version to 1.5.1 to prepare for new commits
2017-03-12 17:01:41 +00:00
Kornel Lesiński
527477ae43 Add file to cmake 2017-02-14 11:58:56 +00:00
DRC
44b2399a94 libjpeg API: Support reading/writing ICC profiles
This commit does the following:

-- Merges the two glueware functions (read_icc_profile() and
write_icc_profile()) from iccjpeg.c, which is contained in downstream
projects such as LCMS, Ghostscript, Mozilla, etc.  These functions were
originally intended for inclusion in libjpeg, but Tom Lane left the IJG
before that could be accomplished.  Since then, programs and libraries
that needed to embed/extract ICC profiles in JPEG files had to include
their own local copy of iccjpeg.c, which is suboptimal.

   -- The new functions were prefixed with jpeg_ and split into separate
   files for the compressor and decompressor, per the existing libjpeg
   coding standards.

   -- jpeg_write_icc_profile() was made slightly more fault-tolerant.
   It will now trigger a libjpeg error if it is called before
   jpeg_start_compress() or if it is passed NULL arguments.

   -- jpeg_read_icc_profile() was made slightly more fault-tolerant.
   It will now trigger a libjpeg error if it is called before
   jpeg_read_header() or if it is passed NULL arguments.  It will also
   now trigger libjpeg warnings if the ICC profile data is corrupt.

   -- The code comments have been wordsmithed.

   -- Note that the one-line setup_read_icc_profile() function was not
   included.  Instead, libjpeg.txt now documents the need to call
   jpeg_save_markers(cinfo, JPEG_APP0 + 2, 0xFFFF) prior to calling
   jpeg_read_header(), if jpeg_read_icc_profile() is to be used.

-- Adds documentation for the new functions to libjpeg.txt.

-- Adds an -icc switch to cjpeg and jpegtran that allows those programs
to embed an ICC profile in the JPEG files they generate.

-- Adds an -icc switch to djpeg that allows that program to extract an
ICC profile from a JPEG file while decompressing.

-- Adds appropriate unit tests for all of the above.

-- Bumps the SO_AGE of the libjpeg API library to indicate the presence
of new API functions.

Note that the licensing information was obtained from:
https://github.com/mm2/Little-CMS/issues/37#issuecomment-66450180
2017-01-19 19:06:22 -06:00
DRC
d9cb76f636 Remove vestigial license text regarding autoconf 2017-01-19 19:05:38 -06:00
DRC
d34d255957 Merge branch 'master' into dev 2017-01-19 19:05:21 -06:00
DRC
a0b7de9a47 Always tweak EXIF w/h tags w/ lossless transforms
... even if using libjpeg v6b emulation.  Previously
adjust_exif_parameters() was only called with libjpeg v7/v8 emulation,
but due to a bug (which this commit also fixes), it only worked properly
with libjpeg v8 emulation.
2017-01-19 19:00:27 -06:00
DRC
2252795571 Fix error w/ lossless crop & libjpeg v7 emulation
The JPEG_LIB_VERSION #ifdef in jtransform_adjust_parameters() was
incorrect, which caused a "Bogus virtual array access" error when
attempting to use the lossless crop feature.

Introduced in c04bd3cc97.

This also adds libjpeg v7 API/ABI emulation to the Travis CI tests.
2017-01-19 18:41:13 -06:00
DRC
eb38b61bfe Include jpeg_skip/crop_scanlines() in jpeg7.dll
... when the in-memory source/destination managers are included.
Oversight in 306e1d2d77 and
3ab68cf563.
2017-01-19 16:44:10 -06:00
DRC
47b29e8cd9 libjpeg.txt: Include partial decomp. in TOC
(oversight)
2017-01-19 15:36:58 -06:00
DRC
e1e816e665 Slightly de-confusify cjpeg, jpegtran usage info
+ bump copyright year
2017-01-19 15:35:54 -06:00
DRC
2fb4d7e337 BUILDING.md: Documentation buglet
`make cygwinpkg` was listed under "Mac".
2016-12-11 22:38:30 -06:00
DRC
8a9b042b26 Merge branch 'master' into dev 2016-12-10 09:35:30 -06:00
DRC
6441018150 LICENSE.md: Include text of BSD/zlib licenses
LICENSE.md is included in the binary distributions as well, so it
doesn't make much sense to refer to license headers in source files that
aren't necessarily going to be there.
2016-12-10 09:32:23 -06:00
DRC
11426a8716 Packaging system: "PACKAGE_NAME" = "PKGNAME"
Using PACKAGE_NAME as a variable name made more sense with autotools,
but now it's more of an inconvenience variable than a convenience
variable.
2016-12-10 09:10:57 -06:00
DRC
67ad535022 Build: Don't require sudo for make tarball
The whole point of `make tarball` is to make it easy for users to create
a binary distribution of libjpeg-turbo on platforms that aren't
supported by our official build system, so requiring root permissions
somewhat defeated that purpose.  Intead, the script now attempts to
detect whether the system has GNU tar or a recent version of BSD tar
that supports setting the ownership of the files in the tarball.
2016-12-10 09:02:53 -06:00
DRC
6c6696e569 Mac pkg: Use PKGNAME for documentation directory
Although there is little chance that we will ever have a package
conflict on OS X, the convention from our Linux packages is to use the
package name, not the project name, for the name of the documentation
directory.
2016-12-09 19:12:25 -06:00
DRC
6530203fdd Build: More GNUInstallDirs improvements
These improvements enable build systems to use GNUInstallDirs to define
custom directory variables.

- The set_dir() macro was renamed to GNUInstallDirs_set_install_dir(),
  in keeping with the module's established macro naming convention.

- Rather than detecting whether the prefix has changed, the new
  GNUInstallDirs_set_install_dir() macro instead examines whether the
  default for the variable in question has changed.  This allows for
  more flexibility, since build systems may decide to change the
  defaults based on factors other than the prefix.  It also enables the
  macro to work properly outside of the module.

- The module now performs directory variable substitution within the
  body of GNUInstallDirs_get_absolute_install_dir().

- The JAVADIR variable is no longer included in GNUInstallDirs.  That
  directory is not part of the GNU spec, and it turns out that various
  operating systems use different conventions for the location of Java
  classes.  Instead, the variable is now implemented in our build
  system as a demonstration of the aforementioned GNUInstallDirs
  enhancements.
2016-12-09 12:09:08 -06:00
DRC
c8358fcbd9 Build: Various improvements to install/pkg system
- GNUInstallDirs: any directory variable can now reference any other
  directory variable by including its name in angle brackets (<>).

- Changed the documentation of the directory variables in BUILDING.md
  accordingly.  This commit also includes some formatting tweaks to
  that section (using boldface for directory names, as is our
  convention.)

- Changed the package scripts such that they use
  CMAKE_INSTALL_DATAROOTDIR rather than CMAKE_INSTALL_DATADIR.

- We no longer override the install dir. defaults on Windows unless
  performing an official build.  It may be useful, for instance, to
  use the GNU defaults when installing into an MSYS environment.
2016-12-08 18:49:14 -06:00
DRC
b0fcd0ccc5 Build: Minor tweaks to GNUInstallDirs defaults
It isn't actually necessary to specify `CMAKE_INSTALL_DEFAULT_MANDIR`
for our official build.  Because `CMAKE_INSTALL_DEFAULT_DATAROOTDIR` is
blank for the official build, the default of "<DATAROOTDIR>/man" will
resolve to "man".

For the same reason, this commit changes the specification of
`CMAKE_INSTALL_DEFAULT_DOCDIR` and `CMAKE_INSTALL_DEFAULT_JAVADIR` in
the official build to be dependent on the data root directory (mainly to
make it obvious what we're doing.)

This commit also tweaks the example CMake command line in the directory
variable documentation so that it shows the correct location of the
CMake argument.
2016-12-07 19:20:46 -06:00
DRC
2b29bca2a9 Build: Fix Debug/RelWithDebInfo build with YASM
YASM requires a debug format to be specified with -g.  Currently the
only combination that I can make work at all is DWARF-2/ELF (YASM
doesn't support Mach-O debugging at all, and its support for CV8/MSVC
and MinGW/DWARF-2 appears to be broken), so debugging is only enabled
automatically for ELF at the moment.  For other formats, we don't
specify -g at all, which is how the old build system behaved.

Fixes #125, Closes #126
2016-12-07 18:18:35 -06:00
DRC
d681fa7626 Build: Set install dirs in a more GNU-friendly way
This builds upon the existing GNUInstallDirs module in CMake but adds
the following features to that module:

- The ability to override the defaults for each install directory
  through a new set of variables (`CMAKE_INSTALL_DEFAULT_*DIR`).

  Before operating system vendors began shipping libjpeg-turbo, it was
  meant to be a run-time drop-in replacement for the system's
  distribution of libjpeg, so it has traditionally installed itself
  under /opt/libjpeg-turbo on Un*x systems by default.  On Windows, it
  has traditionally installed itself under %SystemDrive%\libjpeg-turbo*,
  which is not uncommon behavior for open source libraries (open source
  SDKs tend to install outside of the Program Files directory so as to
  avoid spaces in the directory name.)  At least in the case of Un*x,
  the install directory behavior is based somewhat on the Solaris
  standard, which requires all non-O/S packages to install their files
  under /opt/{package_name}.  I adopted that standard for VirtualGL and
  TurboVNC while working at Sun, because it allowed those packages to be
  located under the same directory on all platforms.  I adopted it for
  libjpeg-turbo because it ensured that our files would never conflict
  with the system's version of libjpeg.  Even though many Un*x
  distributions ship libjpeg-turbo these days, not all of them ship the
  TurboJPEG API library or the Java classes or even the latest version
  of the libjpeg API library, so there are still many cases in which it
  is desirable to install a separate version of libjpeg-turbo than the
  one installed by the system.  Furthermore, installing the files under
  /opt mimics the directory structure of our official binary packages,
  and it makes it very easy to uninstall libjpeg-turbo.

  For these reasons, our build system needs to be able to use
  non-GNU-compliant defaults for each install directory if
  `CMAKE_INSTALL_PREFIX` is set to the default value.

- For each directory variable, the module now detects changes to
  `CMAKE_INSTALL_PREFIX` and changes the directory variable accordingly,
  if the variable has not been changed by the user.

  This makes it easy to switch between our "official" directory
  structure and the GNU-compliant directory structure "on the fly"
  simply by changing `CMAKE_INSTALL_PREFIX`.  Also, this new mechanism
  eliminated the need for the crufty mechanism that previously did the
  same thing just for the library directory variable.

  How it should work:
  - If a dir variable is unset, then the module will set an internal
    property indicating that the dir variable was initialized to its
    default value.
  - If the dir variable ever diverges from its default value, then the
    internal property is cleared, and it cannot be set again without
    unsetting the dir variable.
  - If the install prefix changes, and if the internal property
    indicates that the dir variable is still set to its default value,
    and if the dir variable's value is not being manually changed at the
    same time that the install prefix is being changed, then the dir
    variable's value is automatically changed to the new default value
    for that variable (as determined by the new install prefix.)

- The directory variables are now always cached, regardless of whether
  they were set on the command line or not.  This ensures that they can
  easily be examined and modified after being set, regardless of how they
  were set.

  This was made possible by the introduction of the aforementioned
  `CMAKE_INSTALL_DEFAULT_*DIR` variables.

- Improved directory variable documentation (based on descriptions at
  https://www.gnu.org/prep/standards/html_node/Directory-Variables.html)

- The module now allows "<DATAROOTDIR>" to be used as a placeholder in
  relative directory variables.

  It is replaced "on the fly" with the actual path of
  `CMAKE_INSTALL_DATAROOTDIR`.

This should more closely mimic the behavior of the old autotools build
system while retaining our customizations to it, and it should retain
the behavior of the old CMake build system.

Closes #124
2016-12-07 16:55:38 -06:00
DRC
ff05b6e0de Build: Fix Win "installer" target Java dependency
The correct target name is now "turbojpeg-java".
2016-12-07 14:09:41 -06:00
DRC
e6426d2420 Build: Formatting tweak
(It is our convention to use lowercase for CMake macro/function names)
2016-12-07 10:40:28 -06:00
DRC
2af2fe42a3 Build: Clean up inline keyword detection
Strict C89-conformant compilers don't support the "inline" keyword, but
most of them support "__inline__", and that keyword can be used with the
always_inline atribute as well.  This commit also removes duplicate code
by using a foreach() loop to test the various keywords.
2016-12-05 16:52:54 -06:00
DRC
fcfc6c5eed Fix build when CFLAGS contains -std=c89 (or -ansi)
This is a subtle point, but AC_C_INLINE defines "inline" to be either
"inline", "__inline__", or "__inline".  The subsequent test for
"inline __attribute__((always_inline))" uses this definition.  The
attribute is irrespective of the inline keyword, so whereas
"__inline__ __attribute__((always_inline))" works under C89,
"inline __attribute__((always_inline))" doesn't, and defining INLINE to
the latter causes the build to fail.  The easiest way around this is
simply to define "inline" ahead of "INLINE" in jconfigint.h,
which causes the inline keyword detected by AC_C_INLINE to modify the
INLINE macro if necessary.
2016-12-05 14:02:59 -06:00
DRC
786b649331 Reorg AltiVec detection code
+ advertise that full AltiVec SIMD acceleration is now available on
OpenBSD.

The relevant compilers probably all support C99 or GNU's variation of
C90 that allows variables to be declared anywhere, but our policy is to
conform to the C90 standard, if for no other reason than that it
improves code readability.
2016-12-05 13:14:19 -06:00
Donovan Watteau
f4ba09b33a Detect AltiVec support on OpenBSD 2016-12-05 12:35:15 -06:00
DRC
261db7706d Packaging: Use correct name for SRPM spec file
Per convention, the file should be named {package name}.spec.
2016-12-03 15:51:58 -06:00
Colin Cross
0f4fcced0a Fix sign mismatch comparison warnings
Fixes:
rdppm.c:257:14: warning: comparison of integers of different signs: 'int' and 'unsigned int' [-Wsign-compare]
    if (temp > maxval)
        ~~~~ ^ ~~~~~~
rdppm.c:284:14: warning: comparison of integers of different signs: 'int' and 'unsigned int' [-Wsign-compare]
    if (temp > maxval)
        ~~~~ ^ ~~~~~~
rdppm.c:289:14: warning: comparison of integers of different signs: 'int' and 'unsigned int' [-Wsign-compare]
    if (temp > maxval)
        ~~~~ ^ ~~~~~~
rdppm.c:294:14: warning: comparison of integers of different signs: 'int' and 'unsigned int' [-Wsign-compare]
    if (temp > maxval)
2016-12-03 15:30:59 -06:00
DRC
952191da79 Build: Fix issues when building as a Git submodule
- Replace CMAKE_SOURCE_DIR with CMAKE_CURRENT_SOURCE_DIR
- Replace CMAKE_BINARY_DIR with CMAKE_CURRENT_BINARY_DIR
- Don't use "libjpeg-turbo" in any of the package system filenames
  (because CMAKE_PROJECT_NAME will not be the same if building LJT as
  a submodule.)

Closes #122
2016-12-03 15:21:27 -06:00
DRC
d642da75bd Build: Fix buglet in output of make tjtest 2016-12-03 15:20:36 -06:00
DRC
059c9a5f2a Build: Fix regression in AltiVec SIMD detection
Only the SIMD source files should be built with -maltivec.  Otherwise
the detection code will not be compiled in.
2016-12-03 15:19:41 -06:00
DRC
82bf7f5858 Fix md5cmp on AmigaOS 4 (PowerPC big-endian)
+ Document AmigaOS support in the change log.

Based on:
b4f3b75797

Closes #119
2016-12-01 18:23:32 -06:00
DRC
3582ce90bb Travis: Use xcode7.3 image
The xcode7.2 image is verfallen, verlumpt, verblunget, verkackt

This also ensures that the build scripts are checked out from a
branch matching the libjpeg-turbo repository branch (not strictly
necessary when building from master, but it keeps the code in sync with
dev.)
2016-12-01 01:58:34 -06:00
DRC
94686e3c0f Build: Use wrapper script for gas-preprocessor.pl
The previous hack (adding ${CMAKE_ASM_COMPILER} to CMAKE_ASM_FLAGS)
didn't work in all cases, because more recent versions of CMake place
the includes ahead of the flags (which meant that the real assembler
wasn't the first argument to gas-preprocessor.pl.)
2016-11-25 18:54:55 -06:00
DRC
97205269bc Travis: Fix OS X build
+ migrate to new xcode7.3 image, since xcode7.2 is going away soon.
2016-11-23 18:44:33 -06:00
DRC
27d4c5ea22 Build: Fix RPATH handling
CMAKE_INSTALL_RPATH has to be set before the targets are defined (oops.)

This also explicitly turns on MACOSX_RPATH for the shared libraries
(which is the default with newer versions of CMake but not with 2.8.x.)
The old autotools/libtool build system hard-coded the install name
directory of the OS X shared libraries to libdir, which meant that any
executable that linked against those libraries would also be hard-coded
to look for the libjpeg-turbo libraries in that directory.  @rpath makes
the OS X version of libjpeg-turbo behave like the Linux version, in the
sense that the executables under /opt/libjpeg-turbo/bin will
automatically pick up the libraries under /opt/libjpeg-turbo/lib* by
default, but other executables won't unless they are linked with -rpath.
2016-11-23 18:31:32 -06:00
DRC
6abd39160c Unified CMake-based build system
See #56 for discussion.

Fixes #21, Fixes #29, Fixes #37, Closes #56, Fixes #58, Closes #73
Obviates #82

See also:
https://sourceforge.net/p/libjpeg-turbo/feature-requests/5/
https://sourceforge.net/p/libjpeg-turbo/patches/5/
2016-11-22 13:06:30 -06:00
DRC
9df7ac2e6a BUILDING.md: NASM 2.10+/YASM 1.2.0+ always needed
... for all x86[-64] builds, because we now have both 64-bit and 32-bit
AVX2 SIMD extensions.
2016-11-22 09:33:37 -06:00
DRC
0ff7da7191 Advertise the new AVX2 SIMD extensions
(our story so far ...)
2016-11-22 09:33:37 -06:00
DRC
9fdb8f8553 Merge branch 'master' into dev 2016-11-22 09:33:19 -06:00
DRC
d6d7b53968 AppVeyor: Use built-in MSYS2 MinGW compilers
AppVeyor already has MinGW32 and MinGW64 flavors of GCC 5.3.0
installed under MSYS2, so there is no need to install our own builds of
MinGW.  MinGW-builds is no longer an active project, and we were getting
occasional timeouts while wgetting those files from SourceForge.
Furthermore, GCC 5.3.0 should produce faster code than GCC 4.8.1.
2016-11-21 23:10:02 -06:00
DRC
f9f0c75bb8 BUILDING.md: Clarifications and wordsmithing
Updated out-of-date information, wordsmithed and clarified many
sections, and generally cleaned up the build recipes (including a
complete overhaul of the iOS recipes.)
2016-11-20 21:47:46 -06:00
DRC
3da94de248 Windows build: Add an "uninstall" target 2016-11-20 19:10:54 -06:00
DRC
ab664e35fc BUILDING.md/README.md: Increment libjpeg SO age
Documentation buglet.  This should have been changed in
6ed4d9d110 to reflect the addition of
libjpeg API functions in libjpeg-turbo 1.5.
2016-11-20 16:22:23 -06:00
DRC
ce26e83f47 README.md: Don't use trailing spaces as line break
Makes it easier to maintain this file using editors that automatically
remove trailing spaces.
2016-11-20 16:22:23 -06:00
DRC
74e4c793cd TJBench: Fix regression/-nowrite always enabled
Introduced by eb59b6e72d
2016-11-20 16:22:23 -06:00
DRC
a280fa630c BUILDING.md: Don't use trailing spaces as line break
Makes it easier to maintain this file using editors that automatically
remove trailing spaces.
2016-11-20 16:22:23 -06:00
DRC
6aae007745 CMake build system: Fix the "testclean" target
Regression caused by f9134384b7

This commit also makes the "testclean" target clean up the 4:1:1 test
images.  This was implemented in the autotools build system in
1f3635c496 but was left out of the CMake
build system due to an oversight.
2016-11-20 16:22:23 -06:00
Chris Young
4ad94b2963 Detect AltiVec support on AmigaOS 4 2016-11-18 13:03:28 -06:00
DRC
a949da48da Merge branch 'master' into dev 2016-10-20 19:17:30 -05:00
DRC
2d4b2f14d0 Travis: Deploy to S3 rather than SourceForge
This has the following advantages:
-- It doesn't require checking a private SSH key into the repository.
(With SourceForge, an SSH key is the "keys to the kingdom".)
-- If the S3 key is compromised, it is very easy to revoke it and
generate a new one.
-- The S3 bucket is isolated, so even if it becomes compromised, then
the damage that one could do is limited.
-- It's much easier to manage files through S3's web interface than
through SourceForge.
-- The files are served via HTTPS.
-- Travis fully supports S3 as a deployment target, so this simplifies
.travis.yml somewhat.
2016-10-20 18:17:15 -05:00
DRC
108b1cd9ba Merge branch 'master' into dev 2016-10-20 01:37:40 -05:00
DRC
9366cf0bca Travis: GPG sign Linux binaries/source tarballs
Since we're still deploying our Linux/macOS CI artifacts to a web server
(specifically SourceForge Project Web Services) that doesn't support
HTTPS, it's a good idea to sign them.  But since the private key has to
be checked into the repository, we use a different key for signing the
pre-releases (per project policy, the private signing keys for our
release binaries are never made available on any public server.)
2016-10-20 01:13:11 -05:00
DRC
13e6b151b0 Win: Use YASM if it is in the PATH and NASM isn't
Previously, simd/CMakeLists.txt was hard-coded to use NASM, and it was
necessary to override the NASM variable in order to use YASM.  This
commit changes the behavior such that NASM is still preferred, but YASM
will be used if it is in the PATH and NASM isn't available.  This brings
the actual behavior in line with the behavior described in BUILDING.md.

Based on
b0799a1598

Closes #107
2016-10-11 11:58:20 -05:00
DRC
1a8c68ac5b Merge branch 'master' into dev 2016-10-07 12:55:18 -05:00
DRC
1ee329d617 Travis: Fix deployment issue (2nd attempt) 2016-10-07 12:54:55 -05:00
DRC
fa3bdfb7bc Merge branch 'master' into dev 2016-10-07 05:47:35 -05:00
DRC
b47c5e737f Travis: Fix deployment issue
"Skipping a deployment with the script provider because this branch is
not permitted"
2016-10-07 05:34:33 -05:00
DRC
ce262eb5d7 Fix AppVeyor build on non-master branches
buildljt will clone the Git repository into the temp. directory, even if
the repository is really a local sandbox, so we need to specify the
branch.
2016-10-07 05:20:26 -05:00
DRC
27f817cd11 Travis: Use existing sandbox for official builds
This eliminates the need to specify the remote repository and branch,
and it prevents the code from being checked out twice.
2016-10-07 05:09:16 -05:00
DRC
7884e245bc Merge branch 'master' into dev 2016-10-07 04:51:29 -05:00
DRC
0df2e2188b Add AppVeyor config for Windows pre-release builds 2016-10-07 04:29:37 -05:00
DRC
be908ac024 Travis CI: Fixes to support AVX2 code
-- Use trusty for SIMD builds.  Ubuntu 12.04 is still using NASM 2.09.x,
   which isn't new enough to support AVX2.
-- Add a special test for the SSE2 code path, since it is no longer the
   default.
2016-10-05 14:50:43 -05:00
DRC
ed21f4bd03 Merge branch 'master' into dev 2016-10-05 14:41:14 -05:00
DRC
6d22430a3a Travis: use correct repo/branch for off. builds
Pass the actual repository and branch that Travis is using into the
builtljt script, so the official builds it generates will come from
the same code base as the other tested builds.
2016-10-05 14:36:46 -05:00
DRC
f34f2f5bc6 Fix 'make dist' 2016-10-05 13:36:35 -05:00
DRC
e9e3a2edd7 Travis CI: Use correct key for this repository 2016-10-05 12:38:59 -05:00
DRC
211c69f317 Add Travis CI config for Un*x pre-release builds 2016-10-05 12:33:28 -05:00
DRC
1625253d49 Fix 32-bit non-SIMD FP regression tests
- Introduce a new FLOATTEST value ("387") on Un*x systems that will
  compare the floating point DCT/IDCT algorithms against the expected
  results from the C algorithms when built using 32-bit code and
  -mfpmath=387.
- Extend the Windows regression tests so that they work properly when
  building libjpeg-turbo with 32-bit code and without SIMD, using either
  Visual C++ (tested with 2008, 2010, 2015) or MinGW.
2016-10-04 13:55:00 -05:00
DRC
a0047bdea4 Fix broken build w/ Visual C++ < 2010
Regression introduced by dfefba7752
(Windows doesn't always have stdint.h.)
2016-10-04 13:25:34 -05:00
DRC
7bfb22af12 Fix broken MIPS build
Regression introduced by 9055fb408d

Fixes #104
2016-09-26 18:01:54 -05:00
DRC
ac4a899511 Fix UBSan warning in arithmetic decoder
Very similar to the ones that were fixed in the Huffman decoders in
8e9cef2e6f.  These are innocuous.

Refer to https://bugzilla.mozilla.org/show_bug.cgi?id=1304567.
2016-09-22 14:40:41 -05:00
DRC
dfefba7752 Fix broken build with NDK platforms < android-21
Regression introduced by a09ba29a55

Fixes #103
2016-09-22 14:22:45 -05:00
DRC
4cf67f2363 Bump version to 1.5.2 to prepare for new commits 2016-09-22 14:14:05 -05:00
Roberto Civille Rodrigues
9407cf7f47 README.md: Fix typo
Introduced in 17de518357

Closes #102
2016-09-22 13:39:24 -05:00
DRC
6c36568626 Merge branch 'master' into dev 2016-09-20 18:09:15 -05:00
mayeut
cb88e5da80 ARM64 NEON: Fix another ABI conformance issue
Based on
98a5a9dc89
with wordsmithing by DRC.

In the AArch64 ABI, as in many others, it's forbidden to read/store data
below the stack pointer.  Some SIMD functions were doing just that
(stack pointer misuse) when trying to preserve callee-saved registers,
and this resulted in those registers being restored with incorrect
contents under certain circumstances.

This patch fixes that behavior, and callee-saved registers are now
stored above the stack pointer throughout the function call.  The patch
also removes register saving in places where it is unnecessary for this
ABI, or it makes use of unused scratch regiters instead of callee-saved
registers.

Fixes #97.  Closes #101.

Refer also to https://bugzilla.redhat.com/show_bug.cgi?id=1368569
2016-09-20 17:38:39 -05:00
DRC
e9d9c31fd2 Build: Remove ARMv6 support from 'make iosdmg'
The last iDevice to require ARMv6 was the iPhone 3G, which required iOS
4.2.1 or older.  Our binaries have always required iOS 4.3 or newer,
so I'm not sure if the ARMv6 fork of our binaries was ever useful to
begin with.  In any case, if it ever was useful, it no longer is.  Fat
binaries can still be generated with ARMv6 support by invoking
{build_directory}/pkgscripts/makemacpkg manually.
2016-09-20 11:29:22 -05:00
DRC
077e5bb4e0 Fix out-of-bounds write in partial decomp. feature
Reported by Clang UBSan (refer to
https://bugzilla.mozilla.org/show_bug.cgi?id=1301252 for test image.)
This appears to be a legitimate bug introduced by
3ab68cf563.  Any component array, such
as first_MCU_col and last_MCU_col, should always be able to accommodate
MAX_COMPONENTS values.  The aforementioned test image had 8 components,
which was not enough to make the out-of-bounds write bust out of the
jpeg_decomp_master struct (and fortunately the memory after last_MCU_col
is an integer used as a boolean, so stomping on it will do nothing other
than change the decoder state.)  I crafted another special image that
has 10 components (the maximum allowable), but that was apparently not
enough to bust out of the allocated memory, either.  Thus, it is
posited that the security threat posed by this bug is either extremely
minimal or non-existent.
2016-09-08 22:01:09 -05:00
DRC
a1dd35680d Silence additional UBSan warnings
NOTE: The jdhuff.c/jdphuff.c warnings should have already been silenced
by 8e9cef2e6f, but apparently I need to
be REALLY clear that I'm trying to do pointer arithmetic rather than
dereference an array.  Grrr...

Refer to:
https://bugzilla.mozilla.org/show_bug.cgi?id=1301250
https://bugzilla.mozilla.org/show_bug.cgi?id=1301256
2016-09-08 21:29:58 -05:00
DRC
a09ba29a55 Fix unsigned int overflow in libjpeg memory mgr.
When attempting to decode a malformed JPEG image (refer to
https://bugzilla.mozilla.org/show_bug.cgi?id=1295044) with dimensions
61472 x 32800, the maximum_space variable within the
realize_virt_arrays() function will exceed the maximum value of a 32-bit
integer and will wrap around.  The memory manager subsequently fails
with an "Insufficient memory" error (case 4, in alloc_large()), so this
commit simply causes that error to be triggered earlier, before UBSan
has a chance to complain.

Note that this issue did not ever represent an exploitable security
threat, because the POSIX-based memory manager that we use doesn't ever
do anything meaningful with the value of maximum_space.
jpeg_mem_available() simply sets avail_mem = maximum_space, so the
subsequent behavior of the memory manager is the same regardless of
whether maximum_space is correct or not.  This commit simply removes a
UBSan warning in order to make it easier to detect actual security
issues.
2016-09-08 16:17:05 -05:00
DRC
8ce2c9119a TurboJPEG: Decomp. 4:2:2/4:4:0 JPEGs w/unusual SFs
Normally, 4:2:2 JPEGs have horizontal x vertical luminance,chrominance
sampling factors of 2x1,1x1, and 4:4:0 JPEGs have horizontal x vertical
luminance,chrominance sampling factors of 1x2,1x1.  However, it is
technically legal to create 4:2:2 JPEGs with sampling factors of
2x2,1x2 and 4:4:0 JPEGs with sampling factors of 2x2,2x1, since the
sums of the products of those sampling factors (2x2 + 1x2 + 1x2 and
2x2 + 2x1 + 2x1) are still <= 10.  The libjpeg API correctly decodes
such images, so the TurboJPEG API should as well.

Fixes #92
2016-08-01 11:59:31 -05:00
DRC
db04435165 Silence pedantic GCC6 code formatting warnings
Apparently it's "misleading" to put two self-contained if statements
on a single line.  Who knew?
2016-07-14 13:36:47 -05:00
DRC
7723d7f7d0 Use plain upsampling if merged isn't accelerated
Currently, this only affects ARM, since it is the only platform that
accelerates YCbCr-to-RGB conversion but not merged upsampling.  Even if
"plain" upsampling isn't accelerated, the combination of accelerated
color conversion + unaccelerated plain upsampling is still faster than
the unaccelerated merged upsampling algorithms.

Closes #81
2016-07-13 22:06:11 -05:00
Kornel Lesiński
628c168c86 Implement h1v2 fancy upsampling
This allows fancy upsampling to be used when decompressing 4:2:2 images
that have been losslessly rotated or transposed.

(docs and comments added by DRC)

Based on f63aca945d

Closes #89
2016-07-13 17:28:19 -05:00
DRC
3924ebceb5 AVX2: Perform additional checks for O/S support
cpuid tells us whether the O/S uses extended state management via
XSAVE/XRSTOR, but we have to call xgetbv to verify that it is using
XSAVE/XRSTOR to manage the state of XMM/YMM registers.
2016-07-13 16:03:36 -05:00
DRC
1120ff29a1 Fix AArch64 ABI conformance issue in SIMD code
In the AArch64 ABI, the high (unused) DWORD of a 32-bit argument's
register is undefined, so it was incorrect to use 64-bit
instructions to transfer a JDIMENSION argument in the 64-bit NEON SIMD
functions.  The code worked thus far only because the existing compiler
optimizers weren't smart enough to do anything else with the register in
question, so the upper 32 bits happened to be all zeroes.

The latest builds of Clang/LLVM have a smarter optimizer, and under
certain circumstances, it will attempt to load-combine adjacent 32-bit
integers from one of the libjpeg structures into a single 64-bit integer
and pass that 64-bit integer as a 32-bit argument to one of the SIMD
functions (which is allowed by the ABI, since the upper 32 bits of the
32-bit argument's register are undefined.)  This caused the
libjpeg-turbo regression tests to crash.

This patch tries to use the Wn registers whenever possible.  Otherwise,
it uses a zero-extend instruction to avoid using the upper 32 bits of
the 64-bit registers, which are not guaranteed to be valid for 32-bit
arguments.

Based on 1fbae13021

Closes #91.  Refer also to android-ndk/ndk#110 and
https://llvm.org/bugs/show_bug.cgi?id=28393
2016-07-13 14:36:19 -05:00
DRC
1945ad961b Don't install libturbojpeg.pc if TJPEG disabled 2016-07-12 22:21:20 -05:00
DRC
3dcb85ee9a AVX2: Verify O/S support for AVX2 before enabling
This fixes crashes that would occur when attempting to use
libjpeg-turbo's AVX2 extensions on older O/S's (such as Windows XP or
RHEL 5.)  Even if the CPU supports AVX2, the O/S has to also support
saving/restoring YMM registers when switching contexts.
2016-07-11 20:26:34 -05:00
DRC
1be87b6273 Reformat jsimdcpu[-64].asm to improve readability 2016-07-11 19:42:37 -05:00
DRC
b331385e8a Merge branch 'master' into dev 2016-07-11 13:11:25 -05:00
DRC
b2921f1bcc 32-bit AVX2 implementation of integer quantization 2016-07-08 21:28:48 -05:00
DRC
eaae2cdb16 64-bit AVX2 implementation of integer quantization 2016-07-08 21:15:27 -05:00
DRC
a7c2f97939 AVX2: Avoid expensive AVX-SSE transitions
Refer to
https://software.intel.com/sites/default/files/m/d/4/1/d/8/11MC12_Avoiding_2BAVX-SSE_2BTransition_2BPenalties_2Brh_2Bfinal.pdf
for more information.  This eliminates all AVX-SSE transitions detected
with the Intel SDE tool.
2016-07-08 20:10:24 -05:00
DRC
e06ccbe3f7 64-bit AVX2: Fix bug in IS_ALIGNED_AVX() macro
32 = 1 << 5, not 1 << 8
2016-07-08 13:02:30 -05:00
DRC
67de29b503 32-bit AVX2 impl. of h2v2 & h2v1 merged upsampling 2016-07-08 13:02:30 -05:00
DRC
c22e42e9a2 Optimize 64-bit AVX2 h2v2 fancy upsampler
Reduce register usage and eliminate unnecessary mov instructions
2016-07-08 13:02:30 -05:00
DRC
6d765524bc 32-bit AVX2 impl. of h2v2 & h2v1 upsampling
(Fancy & Plain)
2016-07-08 13:02:30 -05:00
DRC
421d34fd2f 32-bit AVX2 impl. of YCC->RGB color conversion 2016-07-08 13:02:30 -05:00
DRC
c6300ffe4e 32-bit AVX2 impl. of h2v2 & h2v1 downsampling 2016-07-08 13:02:30 -05:00
DRC
6448a5e584 32-bit AVX2 impl. of RGB->YCC/RGB->Gray color conv 2016-07-08 13:02:24 -05:00
DRC
6e9d43e085 Linux/PPC: Only enable AltiVec if CPU supports it
This eliminates "illegal instruction" errors when running libjpeg-turbo
under Linux on PowerPC chips that lack AltiVec support (e.g. the old
7XX/G3 models but also the newer e5500 series.)
2016-07-07 19:02:44 +00:00
DRC
9055fb408d ARM/MIPS: Change the behavior of JSIMD_FORCE*
The JSIMD_FORCE* environment variables previously meant "force the use
of this instruction set if it is available but others are available as
well", but that did nothing on ARM platforms, since there is only ever
one instruction set available.  Since the ARM and MIPS CPU feature
detection code is less than bulletproof, and since there is only one
SIMD instruction set (currently) supported on those platforms, it makes
sense for the JSIMD_FORCE* environment variables on those platforms to
actually force the use of the SIMD instruction set, thus bypassing the
CPU feature detection code.

This addresses a concern raised in #88 whereby parsing /proc/cpuinfo
didn't work within a QEMU environment.  This at least provides a
workaround, allowing users to force-enable or force-disable SIMD
instructions for ARM and MIPS builds of libjpeg-turbo.
2016-07-07 13:38:48 -05:00
DRC
9e6c6a14f8 Bump version to 1.5.1 to prepare for new commits 2016-07-06 16:22:27 +00:00
DRC
7ee3ce9ada Lay the groundwork for 32-bit AVX2 SIMD support 2016-07-05 16:23:06 -05:00
DRC
b5426c52c0 64-bit AVX2 SIMD: Restore instructive comments
This commit adds back instructive comments in the image-space
algorithms, similar to those in the SSE2 code.  These comments make it
easier to follow the flow of data through the algorithms.
2016-06-29 13:56:50 -05:00
DRC
621b29f5b1 64-bit AVX2 impl. of h2v2 & h2v1 merged upsampling 2016-05-31 22:56:11 -05:00
DRC
f1cbc32876 64-bit AVX2 impl. of h2v2 & h2v1 upsampling
(Fancy & Plain)
2016-05-31 22:56:11 -05:00
DRC
72c837da24 64-bit AVX2 impl. of YCC->RGB color conversion 2016-05-31 22:56:11 -05:00
DRC
1c8a475cd4 64-bit AVX2 impl. of h2v2 & h2v1 downsampling 2016-05-31 22:56:11 -05:00
DRC
8880e08771 64-bit AVX2 impl. of RGB->Gray color conversion 2016-05-31 22:56:11 -05:00
DRC
426d787c4c 64-bit AVX2 impl. of RGB->YCC color conversion 2016-05-31 22:56:11 -05:00
DRC
2cf199cbbd Lay the groundwork for 64-bit AVX2 SIMD support 2016-05-31 22:54:38 -05:00
DRC
16b121890c x86-64 SIMD: Optimize argument collection
Expand collect_args/uncollect_args macros so that the number of
arguments can be specified.  This prevents unnecessary push and mov
instructions.

NOTE: On Windows, the push/pop of xmm6 and xmm7 had to be moved to the
other end of the macro to ensure that rsp is aligned on a 16-byte
boundary.
2016-05-31 22:54:37 -05:00
DRC
6cb27c31d9 Bump version to 1.6 alpha1
(to prepare for new features)
2016-05-31 22:54:37 -05:00
DRC
ff5685d534 Reformat SSE/SSE2 SIMD code to improve readability 2016-05-31 22:53:40 -05:00
710 changed files with 144825 additions and 78716 deletions

5
.gitattributes vendored Normal file
View File

@@ -0,0 +1,5 @@
/appveyor.yml export-ignore
/.gitattributes export-ignore
/.github export-ignore
*.ppm binary
/ChangeLog.md conflict-marker-size=8

View File

@@ -1,7 +0,0 @@
dcommander = DRC <dcommander@users.sourceforge.net>
astrand = Peter Åstrand <astrand@cendio.se>
ossman_ = Pierre Ossman <ossman@cendio.se>
const_k = Constantin Kaplinsky <const@tightvnc.com>
atkac = Adam Tkac <atkac@redhat.com>

8
.github/pull_request_template.md vendored Normal file
View File

@@ -0,0 +1,8 @@
**Complete description of the bug fix or feature that this pull request implements**
**Checklist before submitting the pull request, to maximize the chances that the pull request will be accepted**
- [ ] Read CONTRIBUTING.md, a link to which appears under "Helpful resources" below. That document discusses general guidelines for contributing to libjpeg-turbo, as well as the types of contributions that will not be accepted or are unlikely to be accepted.
- [ ] Search the existing issues and pull requests (both open and closed) to ensure that a similar request has not already been submitted and rejected.
- [ ] Discuss the proposed bug fix or feature in a GitHub issue, through direct e-mail with the project maintainer, or on the libjpeg-turbo-devel mailing list.

3
.gitignore vendored
View File

@@ -43,3 +43,6 @@ Makefile
/tjunittest
/wrjpgcom
/yuvjpeg
test_yuv*.jpg
CMakeCache.txt
CTestTestfile.cmake

File diff suppressed because it is too large Load Diff

View File

@@ -1,902 +0,0 @@
*******************************************************************************
** Building on Un*x Platforms (including Cygwin and OS X)
*******************************************************************************
==================
Build Requirements
==================
-- pkg-config
-- autoconf 2.56 or later
-- automake 1.7 or later
-- libtool 1.4 or later
* If using Xcode 4.3 or later on OS X, autoconf and automake are no longer
provided. The easiest way to obtain them is from MacPorts
(http://www.macports.org/).
-- NASM or YASM (if building x86 or x86-64 SIMD extensions)
* NASM 0.98, or 2.01 or later is required for an x86 build (0.99 and 2.00 do
not work properly with libjpeg-turbo's x86 SIMD code.)
* NASM 2.00 or later is required for an x86-64 build.
* NASM 2.07, or 2.11.09 or later is required for an x86-64 Mac build
(2.11.08 does not work properly with libjpeg-turbo's x86-64 SIMD code when
building macho64 objects.) NASM or YASM can be obtained from MacPorts
(http://www.macports.org/).
The binary RPMs released by the NASM project do not work on older Linux
systems, such as Red Hat Enterprise Linux 4. On such systems, you can
easily build and install NASM from a source RPM by downloading one of the
SRPMs from
http://www.nasm.us/pub/nasm/releasebuilds
and executing the following as root:
ARCH=`uname -m`
rpmbuild --rebuild nasm-{version}.src.rpm
rpm -Uvh /usr/src/redhat/RPMS/$ARCH/nasm-{version}.$ARCH.rpm
NOTE: the NASM build will fail if texinfo is not installed.
-- GCC v4.1 or later recommended for best performance
* Beginning with Xcode 4, Apple stopped distributing GCC and switched to
the LLVM compiler. Xcode v4.0 through v4.6 provides a GCC front end
called LLVM-GCC. Unfortunately, as of this writing, neither LLVM-GCC nor
the LLVM (clang) compiler produces optimal performance with libjpeg-turbo.
Building mozjpeg with LLVM-GCC v4.2 results in a 10% performance
degradation when compressing using 64-bit code, relative to building
libjpeg-turbo with GCC v4.2. Building libjpeg-turbo with LLVM (clang)
results in a 20% performance degradation when compressing using 64-bit
code, relative to building libjpeg-turbo with GCC v4.2. If you are
running Snow Leopard or earlier, it is suggested that you continue to use
Xcode v3.2.6, which provides GCC v4.2. If you are using Lion or later, it
is suggested that you install Apple GCC v4.2 or GCC v5 through MacPorts.
-- If building the TurboJPEG Java wrapper, JDK or OpenJDK 1.5 or later is
required. Some systems, such as Solaris 10 and later and Red Hat Enterprise
Linux 5 and later, have this pre-installed. On OS X 10.5 and later, it will
be necessary to install the Java Developer Package, which can be downloaded
from http://developer.apple.com/downloads (Apple ID required.) For systems
that do not have a JDK installed, you can obtain the Oracle Java Development
Kit from http://www.java.com.
==================
Out-of-Tree Builds
==================
Binary objects, libraries, and executables are generated in the same directory
from which configure was executed (the "binary directory"), and this directory
need not necessarily be the same as the mozjpeg source directory. You
can create multiple independent binary directories, in which different versions
of mozjpeg can be built from the same source tree using different
compilers or settings. In the sections below, {build_directory} refers to the
binary directory, whereas {source_directory} refers to the mozjpeg source
directory. For in-tree builds, these directories are the same.
================
Building mozjpeg
================
The following procedure will build mozjpeg on Linux, FreeBSD, Cygwin, and
Solaris/x86 systems (on Solaris, this generates a 32-bit library. See below
for 64-bit build instructions.)
Simple Release tar.gz Source Build
----------------------------------
cd {source_directory}
./configure [additional configure flags]
make
Non-Release Source Build (e.g. GitHub clone)
--------------------------------------------
cd {source_directory}
autoreconf -fiv
cd {build_directory}
sh {source_directory}/configure [additional configure flags]
make
NOTE: Running autoreconf in the source directory is not necessary if building
mozjpeg from one of the official release tarballs.
This will generate the following files under .libs/
libjpeg.a
Static link library for the libjpeg API
libjpeg.so.{version} (Linux, Unix)
libjpeg.{version}.dylib (OS X)
cygjpeg-{version}.dll (Cygwin)
Shared library for the libjpeg API
By default, {version} is 62.2.0, 7.2.0, or 8.1.2, depending on whether
libjpeg v6b (default), v7, or v8 emulation is enabled. If using Cygwin,
{version} is 62, 7, or 8.
libjpeg.so (Linux, Unix)
libjpeg.dylib (OS X)
Development symlink for the libjpeg API
libjpeg.dll.a (Cygwin)
Import library for the libjpeg API
libturbojpeg.a
Static link library for the TurboJPEG API
libturbojpeg.so.0.1.0 (Linux, Unix)
libturbojpeg.0.1.0.dylib (OS X)
cygturbojpeg-0.dll (Cygwin)
Shared library for the TurboJPEG API
libturbojpeg.so (Linux, Unix)
libturbojpeg.dylib (OS X)
Development symlink for the TurboJPEG API
libturbojpeg.dll.a (Cygwin)
Import library for the TurboJPEG API
libjpeg v7 or v8 API/ABI Emulation
----------------------------------
Add --with-jpeg7 to the configure command line to build a version of
mozjpeg that is API/ABI-compatible with libjpeg v7. Add --with-jpeg8 to
the configure command to build a version of mozjpeg that is
API/ABI-compatible with libjpeg v8. See README-turbo.txt for more information
on libjpeg v7 and v8 emulation.
In-Memory Source/Destination Managers
-------------------------------------
When using libjpeg v6b or v7 API/ABI emulation, add --without-mem-srcdst to the
configure command line to build a version of mozjpeg that lacks the
jpeg_mem_src() and jpeg_mem_dest() functions. These functions were not part of
the original libjpeg v6b and v7 APIs, so removing them ensures strict
conformance with those APIs. See README-turbo.txt for more information.
Arithmetic Coding Support
-------------------------
Since the patent on arithmetic coding has expired, this functionality has been
included in this release of mozjpeg. mozjpeg's implementation is
based on the implementation in libjpeg v8, but it works when emulating libjpeg
v7 or v6b as well. The default is to enable both arithmetic encoding and
decoding, but those who have philosophical objections to arithmetic coding can
add --without-arith-enc or --without-arith-dec to the configure command line to
disable encoding or decoding (respectively.)
TurboJPEG Java Wrapper
----------------------
Add --with-java to the configure command line to incorporate an optional Java
Native Interface wrapper into the TurboJPEG shared library and build the Java
front-end classes to support it. This allows the TurboJPEG shared library to
be used directly from Java applications. See java/README for more details.
You can set the JAVAC, JAR, and JAVA configure variables to specify
alternate commands for javac, jar, and java (respectively.) You can also
set the JAVACFLAGS configure variable to specify arguments that should be
passed to the Java compiler when building the front-end classes, and JNI_CFLAGS
to specify arguments that should be passed to the C compiler when building the
JNI wrapper. Run 'configure --help' for more details.
==================
Installing mozjpeg
==================
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/mozjpeg/include and the library
files in /opt/mozjpeg/lib32 (32-bit) or /opt/mozjpeg/lib64
(64-bit.)
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 mozjpeg into
a non-system directory and manipulate the LD_LIBRARY_PATH or create symlinks
to force applications to use mozjpeg instead of libjpeg. See
README-turbo.txt for more information.
=============
Build Recipes
=============
32-bit Build on 64-bit Linux
----------------------------
Add
--host i686-pc-linux-gnu CFLAGS='-O3 -m32' LDFLAGS=-m32
to the configure command line.
64-bit Build on 64-bit OS X
---------------------------
Add
--host x86_64-apple-darwin NASM=/opt/local/bin/nasm
to the configure command line. NASM 2.07 or later from MacPorts must be
installed.
32-bit Build on 64-bit OS X
---------------------------
Add
--host i686-apple-darwin CFLAGS='-O3 -m32' LDFLAGS=-m32
to the configure command line.
64-bit Backward-Compatible Build on 64-bit OS X
-----------------------------------------------
Add
--host x86_64-apple-darwin NASM=/opt/local/bin/nasm \
CFLAGS='-isysroot /Developer/SDKs/MacOSX10.5.sdk \
-mmacosx-version-min=10.5 -O3' \
LDFLAGS='-isysroot /Developer/SDKs/MacOSX10.5.sdk \
-mmacosx-version-min=10.5'
to the configure command line. The OS X 10.5 SDK, and NASM 2.07 or later from
MacPorts, must be installed.
32-bit Backward-Compatible Build on OS X
----------------------------------------
Add
--host i686-apple-darwin \
CFLAGS='-isysroot /Developer/SDKs/MacOSX10.5.sdk \
-mmacosx-version-min=10.5 -O3 -m32' \
LDFLAGS='-isysroot /Developer/SDKs/MacOSX10.5.sdk \
-mmacosx-version-min=10.5 -m32'
to the configure command line. The OS X 10.5 SDK must be installed.
64-bit Library Build on 64-bit Solaris
--------------------------------------
Add
--host x86_64-pc-solaris CFLAGS='-O3 -m64' LDFLAGS=-m64
to the configure command line.
32-bit Build on 64-bit FreeBSD
------------------------------
Add
--host i386-unknown-freebsd CC='gcc -B /usr/lib32' CFLAGS='-O3 -m32' \
LDFLAGS='-B/usr/lib32'
to the configure command line. NASM 2.07 or later from FreeBSD ports must be
installed.
Oracle Solaris Studio
---------------------
Add
CC=cc
to the configure command line. mozjpeg will automatically be built with
the maximum optimization level (-xO5) unless you override CFLAGS.
To build a 64-bit version of mozjpeg using Oracle Solaris Studio, add
--host x86_64-pc-solaris CC=cc CFLAGS='-xO5 -m64' LDFLAGS=-m64
to the configure command line.
MinGW Build on Cygwin
---------------------
Use CMake (see recipes below)
===========
ARM Support
===========
This release of mozjpeg can use ARM NEON SIMD instructions to accelerate
JPEG compression/decompression by approximately 2-4x on ARMv7 and later
platforms. If mozjpeg is configured on an ARM Linux platform, then the
build system will automatically include the NEON SIMD routines, if they are
supported. Build instructions for other ARM-based platforms follow.
Building mozjpeg for iOS
------------------------
iOS platforms, such as the iPhone and iPad, use ARM processors, some of which
support NEON instructions. Additional steps are required in order to build
mozjpeg for these platforms.
Additional build requirements:
gas-preprocessor.pl
(https://raw.githubusercontent.com/libjpeg-turbo/gas-preprocessor/master/gas-preprocessor.pl)
should be installed in your PATH.
ARM 32-bit Build (Xcode 4.6.x and earlier, LLVM-GCC):
Set the following shell variables for simplicity:
Xcode 4.2 and earlier:
IOS_PLATFORMDIR=/Developer/Platforms/iPhoneOS.platform
Xcode 4.3 and later:
IOS_PLATFORMDIR=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform
IOS_SYSROOT=$IOS_PLATFORMDIR/Developer/SDKs/iPhoneOS*.sdk
IOS_GCC=$IOS_PLATFORMDIR/Developer/usr/bin/arm-apple-darwin10-llvm-gcc-4.2
ARMv6 (code will run on all iOS devices, not SIMD-accelerated):
[NOTE: Requires Xcode 4.4.x or earlier]
IOS_CFLAGS="-march=armv6 -mcpu=arm1176jzf-s -mfpu=vfp"
ARMv7 (code will run on iPhone 3GS-4S/iPad 1st-3rd Generation and newer):
IOS_CFLAGS="-march=armv7 -mcpu=cortex-a8 -mtune=cortex-a8 -mfpu=neon"
ARMv7s (code will run on iPhone 5/iPad 4th Generation and newer):
[NOTE: Requires Xcode 4.5 or later]
IOS_CFLAGS="-march=armv7s -mcpu=swift -mtune=swift -mfpu=neon"
Follow the procedure under "Building mozjpeg" above, adding
--host arm-apple-darwin10 \
CC="$IOS_GCC" LD="$IOS_GCC" \
CFLAGS="-mfloat-abi=softfp -isysroot $IOS_SYSROOT -O3 $IOS_CFLAGS" \
LDFLAGS="-mfloat-abi=softfp -isysroot $IOS_SYSROOT $IOS_CFLAGS"
to the configure command line.
ARM 32-bit Build (Xcode 5.0.x and later, Clang):
Set the following shell variables for simplicity:
IOS_PLATFORMDIR=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform
IOS_SYSROOT=$IOS_PLATFORMDIR/Developer/SDKs/iPhoneOS*.sdk
IOS_GCC=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
ARMv7 (code will run on iPhone 3GS-4S/iPad 1st-3rd Generation and newer):
IOS_CFLAGS="-arch armv7"
ARMv7s (code will run on iPhone 5/iPad 4th Generation and newer):
IOS_CFLAGS="-arch armv7s"
Follow the procedure under "Building libjpeg-turbo" above, adding
--host arm-apple-darwin10 \
CC="$IOS_GCC" LD="$IOS_GCC" \
CFLAGS="-mfloat-abi=softfp -isysroot $IOS_SYSROOT -O3 $IOS_CFLAGS" \
LDFLAGS="-mfloat-abi=softfp -isysroot $IOS_SYSROOT $IOS_CFLAGS" \
CCASFLAGS="-no-integrated-as $IOS_CFLAGS"
to the configure command line.
ARMv8 64-bit Build (Xcode 5.0.x and later, Clang):
Code will run on iPhone 5S/iPad Mini 2/iPad Air and newer.
Set the following shell variables for simplicity:
IOS_PLATFORMDIR=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform
IOS_SYSROOT=$IOS_PLATFORMDIR/Developer/SDKs/iPhoneOS*.sdk
IOS_GCC=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
IOS_CFLAGS="-arch arm64"
Follow the procedure under "Building libjpeg-turbo" above, adding
--host aarch64-apple-darwin \
CC="$IOS_GCC" LD="$IOS_GCC" \
CFLAGS="-isysroot $IOS_SYSROOT -O3 $IOS_CFLAGS" \
LDFLAGS="-isysroot $IOS_SYSROOT $IOS_CFLAGS"
to the configure command line.
NOTE: You can also add -miphoneos-version-min={version} to $IOS_CFLAGS above
in order to support older versions of iOS than the default version supported by
the SDK.
Once built, lipo can be used to combine the ARMv6, v7, v7s, and/or v8 variants
into a universal library.
Building libjpeg-turbo for Android
----------------------------------
Building libjpeg-turbo for Android platforms requires the Android NDK
(https://developer.android.com/tools/sdk/ndk) and autotools. The following is
a general recipe script that can be modified for your specific needs.
# Set these variables to suit your needs
NDK_PATH={full path to the "ndk" directory-- for example, /opt/android/ndk}
BUILD_PLATFORM={the platform name for the NDK package you installed--
for example, "windows-x86" or "linux-x86_64" or "darwin-x86_64"}
TOOLCHAIN_VERSION={"4.8", "4.9", "clang3.5", etc. This corresponds to a
toolchain directory under ${NDK_PATH}/toolchains/.}
ANDROID_VERSION={The minimum version of Android to support-- for example,
"16", "19", etc. "21" or later is required for a 64-bit build.}
# 32-bit ARMv7 build
HOST=arm-linux-androideabi
SYSROOT=${NDK_PATH}/platforms/android-${ANDROID_VERSION}/arch-arm
ANDROID_CFLAGS="-march=armv7-a -mfloat-abi=softfp -fprefetch-loop-arrays \
--sysroot=${SYSROOT}"
# 64-bit ARMv8 build
HOST=aarch64-linux-android
SYSROOT=${NDK_PATH}/platforms/android-${ANDROID_VERSION}/arch-arm64
ANDROID_CFLAGS="--sysroot=${SYSROOT}"
TOOLCHAIN=${NDK_PATH}/toolchains/${HOST}-${TOOLCHAIN_VERSION}/prebuilt/${BUILD_PLATFORM}
ANDROID_INCLUDES="-I${SYSROOT}/usr/include -I${TOOLCHAIN}/include"
export CPP=${TOOLCHAIN}/bin/${HOST}-cpp
export AR=${TOOLCHAIN}/bin/${HOST}-ar
export AS=${TOOLCHAIN}/bin/${HOST}-as
export NM=${TOOLCHAIN}/bin/${HOST}-nm
export CC=${TOOLCHAIN}/bin/${HOST}-gcc
export LD=${TOOLCHAIN}/bin/${HOST}-ld
export RANLIB=${TOOLCHAIN}/bin/${HOST}-ranlib
export OBJDUMP=${TOOLCHAIN}/bin/${HOST}-objdump
export STRIP=${TOOLCHAIN}/bin/${HOST}-strip
cd {build_directory}
sh {source_directory}/configure --host=${HOST} \
CFLAGS="${ANDROID_INCLUDES} ${ANDROID_CFLAGS} -O3 -fPIE" \
CPPFLAGS="${ANDROID_INCLUDES} ${ANDROID_CFLAGS}" \
LDFLAGS="${ANDROID_CFLAGS} -pie" --with-simd ${1+"$@"}
make
If building for Android 4.0.x (API level < 16) or earlier, remove -fPIE from
CFLAGS and -pie from LDFLAGS.
*******************************************************************************
** Building on Windows (Visual C++ or MinGW)
*******************************************************************************
==================
Build Requirements
==================
-- CMake (http://www.cmake.org) v2.8.8 or later
-- Microsoft Visual C++ 2005 or later
If you don't already have Visual C++, then the easiest way to get it is by
installing the Windows SDK:
http://msdn.microsoft.com/en-us/windows/bb980924.aspx
The Windows SDK includes both 32-bit and 64-bit Visual C++ compilers and
everything necessary to build mozjpeg.
* You can also use Microsoft Visual Studio Express Edition, which is a free
download. (NOTE: versions prior to 2012 can only be used to build 32-bit
code.)
* If you intend to build mozjpeg from the command line, then add the
appropriate compiler and SDK directories to the INCLUDE, LIB, and PATH
environment variables. This is generally accomplished by executing
vcvars32.bat or vcvars64.bat and SetEnv.cmd. vcvars32.bat and
vcvars64.bat are part of Visual C++ and are located in the same directory
as the compiler. SetEnv.cmd is part of the Windows SDK. You can pass
optional arguments to SetEnv.cmd to specify a 32-bit or 64-bit build
environment.
... OR ...
-- MinGW
MinGW-builds (http://sourceforge.net/projects/mingwbuilds/) or
tdm-gcc (http://tdm-gcc.tdragon.net/) recommended if building on a Windows
machine. Both distributions install a Start Menu link that can be used to
launch a command prompt with the appropriate compiler paths automatically
set.
-- NASM (http://www.nasm.us/) 0.98 or later (NASM 2.05 or later is required for
a 64-bit build)
-- If building the TurboJPEG Java wrapper, JDK 1.5 or later is required. This
can be downloaded from http://www.java.com.
==================
Out-of-Tree Builds
==================
Binary objects, libraries, and executables are generated in the same directory
from which cmake was executed (the "binary directory"), and this directory need
not necessarily be the same as the mozjpeg source directory. You can
create multiple independent binary directories, in which different versions of
mozjpeg can be built from the same source tree using different compilers
or settings. In the sections below, {build_directory} refers to the binary
directory, whereas {source_directory} refers to the mozjpeg source
directory. For in-tree builds, these directories are the same.
================
Building mozjpeg
================
Visual C++ (Command Line)
-------------------------
cd {build_directory}
cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release {source_directory}
nmake
This will build either a 32-bit or a 64-bit version of mozjpeg, depending
on which version of cl.exe is in the PATH.
The following files will be generated under {build_directory}:
jpeg-static.lib
Static link library for the libjpeg API
sharedlib/jpeg{version}.dll
DLL for the libjpeg API
sharedlib/jpeg.lib
Import library for the libjpeg API
turbojpeg-static.lib
Static link library for the TurboJPEG API
turbojpeg.dll
DLL for the TurboJPEG API
turbojpeg.lib
Import library for the TurboJPEG API
{version} is 62, 7, or 8, depending on whether libjpeg v6b (default), v7, or
v8 emulation is enabled.
Visual C++ (IDE)
----------------
Choose the appropriate CMake generator option for your version of Visual Studio
(run "cmake" with no arguments for a list of available generators.) For
instance:
cd {build_directory}
cmake -G "Visual Studio 10" {source_directory}
NOTE: Add "Win64" to the generator name (for example, "Visual Studio 10
Win64") to build a 64-bit version of libjpeg-turbo. Recent versions of CMake
no longer document that. A separate build directory must be used for 32-bit
and 64-bit builds.
You can then open ALL_BUILD.vcproj in Visual Studio and build one of the
configurations in that project ("Debug", "Release", etc.) to generate a full
build of mozjpeg.
This will generate the following files under {build_directory}:
{configuration}/jpeg-static.lib
Static link library for the libjpeg API
sharedlib/{configuration}/jpeg{version}.dll
DLL for the libjpeg API
sharedlib/{configuration}/jpeg.lib
Import library for the libjpeg API
{configuration}/turbojpeg-static.lib
Static link library for the TurboJPEG API
{configuration}/turbojpeg.dll
DLL for the TurboJPEG API
{configuration}/turbojpeg.lib
Import library for the TurboJPEG API
{configuration} is Debug, Release, RelWithDebInfo, or MinSizeRel, depending on
the configuration you built in the IDE, and {version} is 62, 7, or 8,
depending on whether libjpeg v6b (default), v7, or v8 emulation is enabled.
MinGW
-----
NOTE: This assumes that you are building on a Windows machine. If you are
cross-compiling on a Linux/Unix machine, then see "Build Recipes" below.
cd {build_directory}
cmake -G "MinGW Makefiles" {source_directory}
mingw32-make
This will generate the following files under {build_directory}
libjpeg.a
Static link library for the libjpeg API
sharedlib/libjpeg-{version}.dll
DLL for the libjpeg API
sharedlib/libjpeg.dll.a
Import library for the libjpeg API
libturbojpeg.a
Static link library for the TurboJPEG API
libturbojpeg.dll
DLL for the TurboJPEG API
libturbojpeg.dll.a
Import library for the TurboJPEG API
{version} is 62, 7, or 8, depending on whether libjpeg v6b (default), v7, or
v8 emulation is enabled.
Debug Build
-----------
Add "-DCMAKE_BUILD_TYPE=Debug" to the cmake command line. Or, if building with
NMake, remove "-DCMAKE_BUILD_TYPE=Release" (Debug builds are the default with
NMake.)
libjpeg v7 or v8 API/ABI Emulation
-----------------------------------
Add "-DWITH_JPEG7=1" to the cmake command line to build a version of
mozjpeg that is API/ABI-compatible with libjpeg v7. Add "-DWITH_JPEG8=1"
to the cmake command to build a version of mozjpeg that is
API/ABI-compatible with libjpeg v8. See README-turbo.txt for more information
on libjpeg v7 and v8 emulation.
In-Memory Source/Destination Managers
-------------------------------------
When using libjpeg v6b or v7 API/ABI emulation, add -DWITH_MEM_SRCDST=0 to the
CMake command line to build a version of mozjpeg that lacks the
jpeg_mem_src() and jpeg_mem_dest() functions. These functions were not part of
the original libjpeg v6b and v7 APIs, so removing them ensures strict
conformance with those APIs. See README-turbo.txt for more information.
Arithmetic Coding Support
-------------------------
Since the patent on arithmetic coding has expired, this functionality has been
included in this release of mozjpeg. mozjpeg's implementation is
based on the implementation in libjpeg v8, but it works when emulating libjpeg
v7 or v6b as well. The default is to enable both arithmetic encoding and
decoding, but those who have philosophical objections to arithmetic coding can
add "-DWITH_ARITH_ENC=0" or "-DWITH_ARITH_DEC=0" to the cmake command line to
disable encoding or decoding (respectively.)
TurboJPEG Java Wrapper
----------------------
Add "-DWITH_JAVA=1" to the cmake command line to incorporate an optional Java
Native Interface wrapper into the TurboJPEG shared library and build the Java
front-end classes to support it. This allows the TurboJPEG shared library to
be used directly from Java applications. See java/README for more details.
If you are using CMake 2.8, you can set the Java_JAVAC_EXECUTABLE,
Java_JAVA_EXECUTABLE, and Java_JAR_EXECUTABLE CMake variables to specify
alternate commands or locations for javac, jar, and java (respectively.) If
you are using CMake 2.6, set JAVA_COMPILE, JAVA_RUNTIME, and JAVA_ARCHIVE
instead. You can also set the JAVACFLAGS CMake variable to specify arguments
that should be passed to the Java compiler when building the front-end classes.
==================
Installing mozjpeg
==================
You can use the build system to install mozjpeg into a directory of your
choosing (as opposed to creating an installer.) To do this, add:
-DCMAKE_INSTALL_PREFIX={install_directory}
to the cmake command line.
For example,
cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=c:\mozjpeg {source_directory}
nmake install
will install the header files in c:\mozjpeg\include, the library files
in c:\mozjpeg\lib, the DLL's in c:\mozjpeg\bin, and the
documentation in c:\mozjpeg\doc.
=============
Build Recipes
=============
64-bit MinGW Build on Cygwin
----------------------------
cd {build_directory}
CC=/usr/bin/x86_64-w64-mingw32-gcc \
cmake -G "Unix Makefiles" -DCMAKE_SYSTEM_NAME=Windows \
-DCMAKE_RC_COMPILER=/usr/bin/x86_64-w64-mingw32-windres.exe \
{source_directory}
make
This produces a 64-bit build of mozjpeg that does not depend on
cygwin1.dll or other Cygwin DLL's. The mingw64-x86_64-gcc-core and
mingw64-x86_64-gcc-g++ packages (and their dependencies) must be installed.
32-bit MinGW Build on Cygwin
----------------------------
cd {build_directory}
CC=/usr/bin/i686-w64-mingw32-gcc \
cmake -G "Unix Makefiles" -DCMAKE_SYSTEM_NAME=Windows \
-DCMAKE_RC_COMPILER=/usr/bin/i686-w64-mingw32-windres.exe \
{source_directory}
make
This produces a 32-bit build of mozjpeg that does not depend on
cygwin1.dll or other Cygwin DLL's. The mingw64-i686-gcc-core and
mingw64-i686-gcc-g++ packages (and their dependencies) must be installed.
MinGW Build on Linux
--------------------
cd {build_directory}
CC={mingw_binary_path}/i386-mingw32-gcc \
cmake -G "Unix Makefiles" -DCMAKE_SYSTEM_NAME=Windows \
-DCMAKE_AR={mingw_binary_path}/i386-mingw32-ar \
-DCMAKE_RANLIB={mingw_binary_path}/i386-mingw32-ranlib \
{source_directory}
make
*******************************************************************************
** Creating Release Packages
*******************************************************************************
The following commands can be used to create various types of release packages:
Unix/Linux
----------
make rpm
Create Red Hat-style binary RPM package. Requires RPM v4 or later.
make srpm
This runs 'make dist' to create a pristine source tarball, then creates a
Red Hat-style source RPM package from the tarball. Requires RPM v4 or later.
make deb
Create Debian-style binary package. Requires dpkg.
make dmg
Create Macintosh package/disk image. This requires pkgbuild and
productbuild, which are installed by default on OS X 10.7 and later and which
can be obtained by installing Xcode 3.2.6 (with the "Unix Development"
option) on OS X 10.6. Packages built in this manner can be installed on OS X
10.5 and later, but they must be built on OS X 10.6 or later.
make udmg [BUILDDIR32={32-bit build directory}]
On 64-bit OS X systems, this creates a Macintosh package and disk image that
contains universal i386/x86-64 binaries. You should first configure a 32-bit
out-of-tree build of mozjpeg, then configure a 64-bit out-of-tree
build, then run 'make udmg' from the 64-bit build directory. The build
system will look for the 32-bit build under {source_directory}/osxx86 by
default, but you can override this by setting the BUILDDIR32 variable on the
make command line as shown above.
make iosdmg [BUILDDIR32={32-bit build directory}] \
[BUILDDIRARMV6={ARMv6 build directory}] \
[BUILDDIRARMV7={ARMv7 build directory}] \
[BUILDDIRARMV7S={ARMv7s build directory}] \
[BUILDDIRARMV8={ARMv8 build directory}]
On OS X systems, this creates a Macintosh package and disk image in which the
mozjpeg static libraries contain ARM architectures necessary to build
iOS applications. If building on an x86-64 system, the binaries will also
contain the i386 architecture, as with 'make udmg' above. You should first
configure ARMv6, ARMv7, ARMv7s, and/or ARMv8 out-of-tree builds of
mozjpeg (see "Building mozjpeg for iOS" above.) If you are
building an x86-64 version of mozjpeg, you should configure a 32-bit
out-of-tree build as well. Next, build mozjpeg as you would normally,
using an out-of-tree build. When it is built, run 'make iosdmg' from the
build directory. The build system will look for the ARMv6 build under
{source_directory}/iosarmv6 by default, the ARMv7 build under
{source_directory}/iosarmv7 by default, the ARMv7s build under
{source_directory}/iosarmv7s by default, the ARMv8 build under
{source_directory}/iosarmv8 by default, and (if applicable) the 32-bit build
under {source_directory}/osxx86 by default, but you can override this by
setting the BUILDDIR32, BUILDDIRARMV6, BUILDDIRARMV7, BUILDDIRARMV7S, and/or
BUILDDIRARMV8 variables on the make command line as shown above.
NOTE: If including an ARMv8 build in the package, then you may need to use
Xcode's version of lipo instead of the operating system's. To do this, pass
an argument of LIPO="xcrun lipo" on the make command line.
make cygwinpkg
Build a Cygwin binary package.
Windows
-------
If using NMake:
cd {build_directory}
nmake installer
If using MinGW:
cd {build_directory}
make installer
If using the Visual Studio IDE, build the "installer" project.
The installer package (mozjpeg[-gcc][64].exe) will be located under
{build_directory}. If building using the Visual Studio IDE, then the installer
package will be located in a subdirectory with the same name as the
configuration you built (such as {build_directory}\Debug\ or
{build_directory}\Release\).
Building a Windows installer requires the Nullsoft Install System
(http://nsis.sourceforge.net/.) makensis.exe should be in your PATH.
*******************************************************************************
** Regression testing
*******************************************************************************
The most common way to test mozjpeg is by invoking 'make test' on
Unix/Linux platforms or 'ctest' on Windows platforms, once the build has
completed. This runs a series of tests to ensure that mathematical
compatibility has been maintained. This also invokes the TurboJPEG unit tests,
which ensure that the colorspace extensions, YUV encoding, decompression
scaling, and other features of the TurboJPEG C and Java APIs are working
properly (and, by extension, that the equivalent features of the underlying
libjpeg API are also working.)
Invoking 'make testclean' or 'nmake testclean' (if using NMake) or building
the 'testclean' target (if using the Visual Studio IDE) will clean up the
output images generated by 'make test'.
On Unix/Linux platforms, more extensive tests of the TurboJPEG C and Java
wrappers can be run by invoking 'make tjtest'. These extended TurboJPEG tests
essentially iterate through all of the available features of the TurboJPEG APIs
that are not covered by the TurboJPEG unit tests (this includes the lossless
transform options) and compare the images generated by each feature to images
generated using the equivalent feature in the libjpeg API. The extended
TurboJPEG tests are meant to test for regressions in the TurboJPEG wrappers,
not in the underlying libjpeg API library.

File diff suppressed because it is too large Load Diff

15
CODE_OF_CONDUCT.md Normal file
View File

@@ -0,0 +1,15 @@
# Community Participation Guidelines
This repository is governed by Mozilla's code of conduct and etiquette guidelines.
For more details, please read the
[Mozilla Community Participation Guidelines](https://www.mozilla.org/about/governance/policies/participation/).
## How to Report
For more information on how to report violations of the Community Participation Guidelines, please read our '[How to Report](https://www.mozilla.org/about/governance/policies/participation/reporting/)' page.
<!--
## Project Specific Etiquette
In some cases, there will be additional project etiquette i.e.: (https://bugzilla.mozilla.org/page.cgi?id=etiquette.html).
Please update for your project.
-->

File diff suppressed because it is too large Load Diff

View File

@@ -1,30 +1,33 @@
libjpeg-turbo Licenses
======================
libjpeg-turbo is covered by three compatible BSD-style open source licenses:
libjpeg-turbo is covered by two compatible BSD-style open source licenses:
- The IJG (Independent JPEG Group) License, which is listed in
[README.ijg](README.ijg)
This license applies to the libjpeg API library and associated programs
(any code inherited from libjpeg, and any modifications to that code.)
This license applies to the libjpeg API library and associated programs,
including any code inherited from libjpeg and any modifications to that
code. Note that the libjpeg-turbo SIMD source code bears the
[zlib License](https://opensource.org/licenses/Zlib), but in the context of
the overall libjpeg API library, the terms of the zlib License are subsumed
by the terms of the IJG License.
- The Modified (3-clause) BSD License, which is listed in
[turbojpeg.c](turbojpeg.c)
- The Modified (3-clause) BSD License, which is listed below
This license covers the TurboJPEG API library and associated programs.
- The zlib License, which is listed in [simd/jsimdext.inc](simd/jsimdext.inc)
This license is a subset of the other two, and it covers the libjpeg-turbo
SIMD extensions.
This license applies to the TurboJPEG API library and associated programs, as
well as the build system. Note that the TurboJPEG API library wraps the
libjpeg API library, so in the context of the overall TurboJPEG API library,
both the terms of the IJG License and the terms of the Modified (3-clause)
BSD License apply.
Complying with the libjpeg-turbo Licenses
=========================================
This section provides a roll-up of the libjpeg-turbo licensing terms, to the
best of our understanding.
best of our understanding. This is not a license in and of itself. It is
intended solely for clarification.
1. If you are distributing a modified version of the libjpeg-turbo source,
then:
@@ -38,7 +41,7 @@ best of our understanding.
- Clauses 1 and 3 of the zlib License
2. You must add your own copyright notice to the header of each source
file you modified, so others can tell that you modified that file (if
file you modified, so others can tell that you modified that file. (If
there is not an existing copyright header in that file, then you can
simply add a notice stating that you modified the file.)
@@ -66,7 +69,7 @@ best of our understanding.
2. If your binary distribution includes or uses the TurboJPEG API, then
your product documentation must include the text of the Modified BSD
License.
License (see below.)
**Origin**
- Clause 2 of the Modified BSD License
@@ -86,3 +89,47 @@ best of our understanding.
- IJG License
- Modified BSD License
- zlib License
The Modified (3-clause) BSD License
===================================
Copyright (C)2009-2024 D. R. Commander. All Rights Reserved.<br>
Copyright (C)2015 Viktor Szathmáry. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
- Neither the name of the libjpeg-turbo Project nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
Why Two Licenses?
=================
The zlib License could have been used instead of the Modified (3-clause) BSD
License, and since the IJG License effectively subsumes the distribution
conditions of the zlib License, this would have effectively placed
libjpeg-turbo binary distributions under the IJG License. However, the IJG
License specifically refers to the Independent JPEG Group and does not extend
attribution and endorsement protections to other entities. Thus, it was
desirable to choose a license that granted us the same protections for new code
that were granted to the IJG for code derived from their software.

View File

@@ -1,792 +0,0 @@
lib_LTLIBRARIES = libjpeg.la
libjpeg_la_LDFLAGS = -version-info ${LIBTOOL_CURRENT}:${SO_MINOR_VERSION}:${SO_AGE} -no-undefined
include_HEADERS = jerror.h jmorecfg.h jpeglib.h
if WITH_TURBOJPEG
lib_LTLIBRARIES += libturbojpeg.la
libturbojpeg_la_LDFLAGS = -version-info 1:0:1 -no-undefined
include_HEADERS += turbojpeg.h
endif
nodist_include_HEADERS = jconfig.h
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = pkgscripts/libjpeg.pc pkgscripts/libturbojpeg.pc
HDRS = jchuff.h jcmaster.h jdct.h jdhuff.h jerror.h jinclude.h jmemsys.h \
jmorecfg.h jpegint.h jpeglib.h jversion.h jsimd.h jsimddct.h jpegcomp.h \
jpeg_nbits_table.h
libjpeg_la_SOURCES = $(HDRS) jcapimin.c jcapistd.c jccoefct.c jccolor.c \
jcdctmgr.c jcext.c jchuff.c jcinit.c jcmainct.c jcmarker.c \
jcmaster.c jcomapi.c jcparam.c jcphuff.c jcprepct.c jcsample.c \
jctrans.c jdapimin.c jdapistd.c jdatadst.c jdatasrc.c jdcoefct.c \
jdcolor.c jddctmgr.c jdhuff.c jdinput.c jdmainct.c jdmarker.c \
jdmaster.c jdmerge.c jdphuff.c jdpostct.c jdsample.c jdtrans.c \
jerror.c jfdctflt.c jfdctfst.c jfdctint.c jidctflt.c jidctfst.c \
jidctint.c jidctred.c jquant1.c jquant2.c jutils.c jmemmgr.c jmemnobs.c
if WITH_ARITH
libjpeg_la_SOURCES += jaricom.c
endif
if WITH_ARITH_ENC
libjpeg_la_SOURCES += jcarith.c
endif
if WITH_ARITH_DEC
libjpeg_la_SOURCES += jdarith.c
endif
SUBDIRS = java
if WITH_TURBOJPEG
libturbojpeg_la_SOURCES = $(libjpeg_la_SOURCES) turbojpeg.c turbojpeg.h \
transupp.c transupp.h jdatadst-tj.c jdatasrc-tj.c
if WITH_JAVA
libturbojpeg_la_SOURCES += turbojpeg-jni.c
libturbojpeg_la_CFLAGS = ${JNI_CFLAGS}
TJMAPFILE = turbojpeg-mapfile.jni
else
TJMAPFILE = turbojpeg-mapfile
endif
libturbojpeg_la_SOURCES += $(TJMAPFILE)
if VERSION_SCRIPT
libturbojpeg_la_LDFLAGS += $(VERSION_SCRIPT_FLAG)$(srcdir)/$(TJMAPFILE)
endif
endif
if VERSION_SCRIPT
libjpeg_la_LDFLAGS += $(VERSION_SCRIPT_FLAG)libjpeg.map
endif
if WITH_SIMD
SUBDIRS += simd
libjpeg_la_LIBADD = simd/libsimd.la
libturbojpeg_la_LIBADD = simd/libsimd.la
else
libjpeg_la_SOURCES += jsimd_none.c
endif
bin_PROGRAMS = cjpeg djpeg jpegtran rdjpgcom wrjpgcom
noinst_PROGRAMS = jcstest jpegyuv yuvjpeg
if WITH_TURBOJPEG
bin_PROGRAMS += tjbench
noinst_PROGRAMS += tjunittest
tjbench_SOURCES = tjbench.c bmp.h bmp.c tjutil.h tjutil.c rdbmp.c rdppm.c \
wrbmp.c wrppm.c
tjbench_LDADD = libturbojpeg.la libjpeg.la -lm
tjbench_CFLAGS = -DBMP_SUPPORTED -DPPM_SUPPORTED
tjunittest_SOURCES = tjunittest.c tjutil.h tjutil.c
tjunittest_LDADD = libturbojpeg.la
endif
cjpeg_SOURCES = cdjpeg.h cderror.h cdjpeg.c cjpeg.c rdgif.c rdppm.c rdswitch.c rdjpeg.c
if WITH_12BIT
else
cjpeg_SOURCES += rdbmp.c rdtarga.c
endif
cjpeg_LDADD = libjpeg.la
cjpeg_CFLAGS = -DGIF_SUPPORTED -DPPM_SUPPORTED
if WITH_12BIT
else
cjpeg_CFLAGS += -DBMP_SUPPORTED -DTARGA_SUPPORTED
endif
if HAVE_LIBPNG
cjpeg_CFLAGS += -DPNG_SUPPORTED $(libpng_CFLAGS)
cjpeg_LDADD += $(libpng_LIBS)
cjpeg_SOURCES += rdpng.c
endif
djpeg_SOURCES = cdjpeg.h cderror.h cdjpeg.c djpeg.c rdcolmap.c rdswitch.c \
wrgif.c wrppm.c
if WITH_12BIT
else
djpeg_SOURCES += wrbmp.c wrtarga.c
endif
djpeg_LDADD = libjpeg.la
djpeg_CFLAGS = -DGIF_SUPPORTED -DPPM_SUPPORTED
if WITH_12BIT
else
djpeg_CFLAGS += -DBMP_SUPPORTED -DTARGA_SUPPORTED
endif
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
jcstest_SOURCES = jcstest.c
jcstest_LDADD = libjpeg.la
jpegyuv_SOURCES = jpegyuv.c
jpegyuv_LDADD = libjpeg.la
yuvjpeg_SOURCES = yuvjpeg.c
yuvjpeg_LDADD = libjpeg.la
dist_man1_MANS = cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 wrjpgcom.1
DOCS= coderules.txt jconfig.txt change.log rdrle.c wrrle.c BUILDING.md \
ChangeLog.md
dist_doc_DATA = README.ijg README.md libjpeg.txt structure.txt usage.txt \
wizard.txt LICENSE.md
exampledir = $(docdir)
dist_example_DATA = example.c
EXTRA_DIST = win release $(DOCS) testimages CMakeLists.txt \
sharedlib/CMakeLists.txt cmakescripts libjpeg.map.in doc doxygen.config \
doxygen-extra.css jccolext.c jdcolext.c jdcol565.c jdmrgext.c jdmrg565.c \
jstdhuff.c jdcoefct.h jdmainct.h jdmaster.h jdsample.h wrppm.h \
md5/CMakeLists.txt
dist-hook:
rm -rf `find $(distdir) -name .svn`
SUBDIRS += md5
if WITH_12BIT
TESTORIG = testorig12.jpg
MD5_JPEG_RGB_ISLOW = 9620f424569594bb9242b48498ad801f
MD5_PPM_RGB_ISLOW = f3301d2219783b8b3d942b7239fa50c0
MD5_JPEG_422_IFAST_OPT = 7322e3bd2f127f7de4b40d4480ce60e4
MD5_PPM_422_IFAST = 79807fa552899e66a04708f533e16950
MD5_PPM_422M_IFAST = 07737bfe8a7c1c87aaa393a0098d16b0
MD5_JPEG_420_IFAST_Q100_PROG = a1da220b5604081863a504297ed59e55
MD5_PPM_420_Q100_IFAST = 1b3730122709f53d007255e8dfd3305e
MD5_PPM_420M_Q100_IFAST = 980a1a3c5bf9510022869d30b7d26566
MD5_JPEG_GRAY_ISLOW = 235c90707b16e2e069f37c888b2636d9
MD5_PPM_GRAY_ISLOW = 7213c10af507ad467da5578ca5ee1fca
MD5_PPM_GRAY_ISLOW_RGB = e96ee81c30a6ed422d466338bd3de65d
MD5_JPEG_420S_IFAST_OPT = 7af8e60be4d9c227ec63ac9b6630855e
MD5_JPEG_3x2_FLOAT_PROG_SSE = a8c17daf77b457725ec929e215b603f8
MD5_PPM_3x2_FLOAT_SSE = 42876ab9e5c2f76a87d08db5fbd57956
MD5_JPEG_3x2_FLOAT_PROG_32BIT = a8c17daf77b457725ec929e215b603f8
MD5_PPM_3x2_FLOAT_32BIT = 42876ab9e5c2f76a87d08db5fbd57956
MD5_PPM_3x2_FLOAT_64BIT = d6fbc71153b3d8ded484dbc17c7b9cf4
MD5_JPEG_3x2_IFAST_PROG = 1396cc2b7185cfe943d408c9d305339e
MD5_PPM_3x2_IFAST = 3975985ef6eeb0a2cdc58daa651ccc00
MD5_PPM_420M_ISLOW_2_1 = 4ca6be2a6f326ff9eaab63e70a8259c0
MD5_PPM_420M_ISLOW_15_8 = 12aa9f9534c1b3d7ba047322226365eb
MD5_PPM_420M_ISLOW_13_8 = f7e22817c7b25e1393e4ec101e9d4e96
MD5_PPM_420M_ISLOW_11_8 = 800a16f9f4dc9b293197bfe11be10a82
MD5_PPM_420M_ISLOW_9_8 = 06b7a92a9bc69f4dc36ec40f1937d55c
MD5_PPM_420M_ISLOW_7_8 = 3ec444a14a4ab4eab88ffc49c48eca43
MD5_PPM_420M_ISLOW_3_4 = 3e726b7ea872445b19437d1c1d4f0d93
MD5_PPM_420M_ISLOW_5_8 = a8a771abdc94301d20ffac119b2caccd
MD5_PPM_420M_ISLOW_1_2 = b419124dd5568b085787234866102866
MD5_PPM_420M_ISLOW_3_8 = 343d19015531b7bbe746124127244fa8
MD5_PPM_420M_ISLOW_1_4 = 35fd59d866e44659edfa3c18db2a3edb
MD5_PPM_420M_ISLOW_1_8 = ccaed48ac0aedefda5d4abe4013f4ad7
MD5_PPM_420_ISLOW_SKIP15_31 = 86664cd9dc956536409e44e244d20a97
MD5_PPM_420_ISLOW_PROG_CROP62x62_71_71 = 452a21656115a163029cfba5c04fa76a
MD5_PPM_444_ISLOW_SKIP1_6 = ef63901f71ef7a75cd78253fc0914f84
MD5_PPM_444_ISLOW_PROG_CROP98x98_13_13 = 15b173fb5872d9575572fbcc1b05956f
MD5_JPEG_CROP = cdb35ff4b4519392690ea040c56ea99c
else
TESTORIG = testorig.jpg
MD5_JPEG_RGB_ISLOW = 768e970dd57b340ff1b83c9d3d47c77b
MD5_PPM_RGB_ISLOW = 00a257f5393fef8821f2b88ac7421291
MD5_BMP_RGB_ISLOW_565 = f07d2e75073e4bb10f6c6f4d36e2e3be
MD5_BMP_RGB_ISLOW_565D = 4cfa0928ef3e6bb626d7728c924cfda4
MD5_JPEG_422_IFAST_OPT = 2540287b79d913f91665e660303ab2c8
MD5_PPM_422_IFAST = 35bd6b3f833bad23de82acea847129fa
MD5_PPM_422M_IFAST = 8dbc65323d62cca7c91ba02dd1cfa81d
MD5_BMP_422M_IFAST_565 = 3294bd4d9a1f2b3d08ea6020d0db7065
MD5_BMP_422M_IFAST_565D = da98c9c7b6039511be4a79a878a9abc1
MD5_JPEG_420_IFAST_Q100_PROG = 990cbe0329c882420a2094da7e5adade
MD5_PPM_420_Q100_IFAST = 5a732542015c278ff43635e473a8a294
MD5_PPM_420M_Q100_IFAST = ff692ee9323a3b424894862557c092f1
MD5_JPEG_GRAY_ISLOW = 72b51f894b8f4a10b3ee3066770aa38d
MD5_PPM_GRAY_ISLOW = 8d3596c56eace32f205deccc229aa5ed
MD5_PPM_GRAY_ISLOW_RGB = 116424ac07b79e5e801f00508eab48ec
MD5_BMP_GRAY_ISLOW_565 = 12f78118e56a2f48b966f792fedf23cc
MD5_BMP_GRAY_ISLOW_565D = bdbbd616441a24354c98553df5dc82db
MD5_JPEG_420S_IFAST_OPT = 388708217ac46273ca33086b22827ed8
# See README.md for more details on why this next bit is necessary.
MD5_JPEG_3x2_FLOAT_PROG_SSE = 343e3f8caf8af5986ebaf0bdc13b5c71
MD5_PPM_3x2_FLOAT_SSE = 1a75f36e5904d6fc3a85a43da9ad89bb
MD5_JPEG_3x2_FLOAT_PROG_32BIT = 9bca803d2042bd1eb03819e2bf92b3e5
MD5_PPM_3x2_FLOAT_32BIT = f6bfab038438ed8f5522fbd33595dcdc
MD5_PPM_3x2_FLOAT_64BIT = 0e917a34193ef976b679a6b069b1be26
MD5_JPEG_3x2_IFAST_PROG = 1ee5d2c1a77f2da495f993c8c7cceca5
MD5_PPM_3x2_IFAST = fd283664b3b49127984af0a7f118fccd
MD5_JPEG_420_ISLOW_ARI = e986fb0a637a8d833d96e8a6d6d84ea1
MD5_JPEG_444_ISLOW_PROGARI = 0a8f1c8f66e113c3cf635df0a475a617
MD5_PPM_420M_IFAST_ARI = 72b59a99bcf1de24c5b27d151bde2437
MD5_JPEG_420_ISLOW = 9a68f56bc76e466aa7e52f415d0f4a5f
MD5_PPM_420M_ISLOW_2_1 = 9f9de8c0612f8d06869b960b05abf9c9
MD5_PPM_420M_ISLOW_15_8 = b6875bc070720b899566cc06459b63b7
MD5_PPM_420M_ISLOW_13_8 = bc3452573c8152f6ae552939ee19f82f
MD5_PPM_420M_ISLOW_11_8 = d8cc73c0aaacd4556569b59437ba00a5
MD5_PPM_420M_ISLOW_9_8 = d25e61bc7eac0002f5b393aa223747b6
MD5_PPM_420M_ISLOW_7_8 = ddb564b7c74a09494016d6cd7502a946
MD5_PPM_420M_ISLOW_3_4 = 8ed8e68808c3fbc4ea764fc9d2968646
MD5_PPM_420M_ISLOW_5_8 = a3363274999da2366a024efae6d16c9b
MD5_PPM_420M_ISLOW_1_2 = e692a315cea26b988c8e8b29a5dbcd81
MD5_PPM_420M_ISLOW_3_8 = 79eca9175652ced755155c90e785a996
MD5_PPM_420M_ISLOW_1_4 = 79cd778f8bf1a117690052cacdd54eca
MD5_PPM_420M_ISLOW_1_8 = 391b3d4aca640c8567d6f8745eb2142f
MD5_BMP_420_ISLOW_256 = 4980185e3776e89bd931736e1cddeee6
MD5_BMP_420_ISLOW_565 = bf9d13e16c4923b92e1faa604d7922cb
MD5_BMP_420_ISLOW_565D = 6bde71526acc44bcff76f696df8638d2
MD5_BMP_420M_ISLOW_565 = 8dc0185245353cfa32ad97027342216f
MD5_BMP_420M_ISLOW_565D =d1be3a3339166255e76fa50a0d70d73e
MD5_PPM_420_ISLOW_SKIP15_31 = c4c65c1e43d7275cd50328a61e6534f0
MD5_PPM_420_ISLOW_ARI_SKIP16_139 = 087c6b123db16ac00cb88c5b590bb74a
MD5_PPM_420_ISLOW_PROG_CROP62x62_71_71 = 26eb36ccc7d1f0cb80cdabb0ac8b5d99
MD5_PPM_420_ISLOW_ARI_CROP53x53_4_4 = 886c6775af22370257122f8b16207e6d
MD5_PPM_444_ISLOW_SKIP1_6 = 5606f86874cf26b8fcee1117a0a436a6
MD5_PPM_444_ISLOW_PROG_CROP98x98_13_13 = db87dc7ce26bcdc7a6b56239ce2b9d6c
MD5_PPM_444_ISLOW_ARI_CROP37x37_0_0 = cb57b32bd6d03e35432362f7bf184b6d
MD5_JPEG_CROP = b4197f377e621c4e9b1d20471432610d
endif
.PHONY: test
test: tjquicktest tjbittest bittest
if CROSS_COMPILING
tjquicktest: testclean
else
tjquicktest: testclean all
endif
if WITH_TURBOJPEG
if WITH_JAVA
$(JAVA) -cp java/turbojpeg.jar -Djava.library.path=.libs TJUnitTest
$(JAVA) -cp java/turbojpeg.jar -Djava.library.path=.libs TJUnitTest -bi
$(JAVA) -cp java/turbojpeg.jar -Djava.library.path=.libs TJUnitTest -yuv
$(JAVA) -cp java/turbojpeg.jar -Djava.library.path=.libs TJUnitTest -yuv -noyuvpad
$(JAVA) -cp java/turbojpeg.jar -Djava.library.path=.libs TJUnitTest -yuv -bi
$(JAVA) -cp java/turbojpeg.jar -Djava.library.path=.libs TJUnitTest -yuv -bi -noyuvpad
endif
./tjunittest
./tjunittest -alloc
./tjunittest -yuv
./tjunittest -yuv -alloc
./tjunittest -yuv -noyuvpad
endif
echo GREAT SUCCESS!
if CROSS_COMPILING
tjbittest: testclean
else
tjbittest: testclean all
endif
if WITH_TURBOJPEG
MD5_PPM_GRAY_TILE = 89d3ca21213d9d864b50b4e4e7de4ca6
MD5_PPM_420_8x8_TILE = 847fceab15c5b7b911cb986cf0f71de3
MD5_PPM_420_16x16_TILE = ca45552a93687e078f7137cc4126a7b0
MD5_PPM_420_32x32_TILE = d8676f1d6b68df358353bba9844f4a00
MD5_PPM_420_64x64_TILE = 4e4c1a3d7ea4bace4f868bcbe83b7050
MD5_PPM_420_128x128_TILE = f24c3429c52265832beab9df72a0ceae
MD5_PPM_420M_8x8_TILE = bc25320e1f4c31ce2e610e43e9fd173c
MD5_PPM_420M_TILE = 75ffdf14602258c5c189522af57fa605
MD5_PPM_422_8x8_TILE = d83dacd9fc73b0a6f10c09acad64eb1e
MD5_PPM_422_16x16_TILE = 35077fb610d72dd743b1eb0cbcfe10fb
MD5_PPM_422_32x32_TILE = e6902ed8a449ecc0f0d6f2bf945f65f7
MD5_PPM_422_64x64_TILE = 2b4502a8f316cedbde1da7bce3d2231e
MD5_PPM_422_128x128_TILE = f0b5617d578f5e13c8eee215d64d4877
MD5_PPM_422M_8x8_TILE = 828941d7f41cd6283abd6beffb7fd51d
MD5_PPM_422M_TILE = e877ae1324c4a280b95376f7f018172f
MD5_PPM_444_TILE = 7964e41e67cfb8d0a587c0aa4798f9c3
# Test compressing from/decompressing to an arbitrary subregion of a larger
# image buffer
cp $(srcdir)/testimages/testorig.ppm testout_tile.ppm
TJ_REVERT=1 ./tjbench testout_tile.ppm 95 -rgb -quiet -tile -benchtime 0.01 >/dev/null 2>&1
for i in 8 16 32 64 128; do \
md5/md5cmp $(MD5_PPM_GRAY_TILE) testout_tile_GRAY_Q95_$$i\x$$i.ppm; \
done
md5/md5cmp $(MD5_PPM_420_8x8_TILE) testout_tile_420_Q95_8x8.ppm
md5/md5cmp $(MD5_PPM_420_16x16_TILE) testout_tile_420_Q95_16x16.ppm
md5/md5cmp $(MD5_PPM_420_32x32_TILE) testout_tile_420_Q95_32x32.ppm
md5/md5cmp $(MD5_PPM_420_64x64_TILE) testout_tile_420_Q95_64x64.ppm
md5/md5cmp $(MD5_PPM_420_128x128_TILE) testout_tile_420_Q95_128x128.ppm
md5/md5cmp $(MD5_PPM_422_8x8_TILE) testout_tile_422_Q95_8x8.ppm
md5/md5cmp $(MD5_PPM_422_16x16_TILE) testout_tile_422_Q95_16x16.ppm
md5/md5cmp $(MD5_PPM_422_32x32_TILE) testout_tile_422_Q95_32x32.ppm
md5/md5cmp $(MD5_PPM_422_64x64_TILE) testout_tile_422_Q95_64x64.ppm
md5/md5cmp $(MD5_PPM_422_128x128_TILE) testout_tile_422_Q95_128x128.ppm
for i in 8 16 32 64 128; do \
md5/md5cmp $(MD5_PPM_444_TILE) testout_tile_444_Q95_$$i\x$$i.ppm; \
done
rm -f testout_tile_GRAY_* testout_tile_420_* testout_tile_422_* testout_tile_444_*
TJ_REVERT=1 ./tjbench testout_tile.ppm 95 -rgb -fastupsample -quiet -tile -benchtime 0.01 >/dev/null 2>&1
md5/md5cmp $(MD5_PPM_420M_8x8_TILE) testout_tile_420_Q95_8x8.ppm
for i in 16 32 64 128; do \
md5/md5cmp $(MD5_PPM_420M_TILE) testout_tile_420_Q95_$$i\x$$i.ppm; \
done
md5/md5cmp $(MD5_PPM_422M_8x8_TILE) testout_tile_422_Q95_8x8.ppm
for i in 16 32 64 128; do \
md5/md5cmp $(MD5_PPM_422M_TILE) testout_tile_422_Q95_$$i\x$$i.ppm; \
done
rm -f testout_tile_GRAY_* testout_tile_420_* testout_tile_422_* testout_tile_444_* testout_tile.ppm
echo GREAT SUCCESS!
endif
if CROSS_COMPILING
bittest: testclean
else
bittest: testclean all
endif
# These tests are carefully crafted to provide full coverage of as many of the
# underlying algorithms as possible (including all of the SIMD-accelerated
# ones.)
# CC: null SAMP: fullsize FDCT: islow ENT: huff
./cjpeg -revert -rgb -dct int -outfile testout_rgb_islow.jpg $(srcdir)/testimages/testorig.ppm
md5/md5cmp $(MD5_JPEG_RGB_ISLOW) testout_rgb_islow.jpg
# CC: null SAMP: fullsize IDCT: islow ENT: huff
./djpeg -dct int -ppm -outfile testout_rgb_islow.ppm testout_rgb_islow.jpg
md5/md5cmp $(MD5_PPM_RGB_ISLOW) testout_rgb_islow.ppm
rm -f testout_rgb_islow.ppm
if WITH_12BIT
rm -f testout_rgb_islow.jpg
else
# CC: RGB->RGB565 SAMP: fullsize IDCT: islow ENT: huff
./djpeg -dct int -rgb565 -dither none -bmp -outfile testout_rgb_islow_565.bmp testout_rgb_islow.jpg
md5/md5cmp $(MD5_BMP_RGB_ISLOW_565) testout_rgb_islow_565.bmp
rm -f testout_rgb_islow_565.bmp
# CC: RGB->RGB565 (dithered) SAMP: fullsize IDCT: islow ENT: huff
./djpeg -dct int -rgb565 -bmp -outfile testout_rgb_islow_565D.bmp testout_rgb_islow.jpg
md5/md5cmp $(MD5_BMP_RGB_ISLOW_565D) testout_rgb_islow_565D.bmp
rm -f testout_rgb_islow_565D.bmp testout_rgb_islow.jpg
endif
# CC: RGB->YCC SAMP: fullsize/h2v1 FDCT: ifast ENT: 2-pass huff
./cjpeg -revert -sample 2x1 -dct fast -opt -outfile testout_422_ifast_opt.jpg $(srcdir)/testimages/testorig.ppm
md5/md5cmp $(MD5_JPEG_422_IFAST_OPT) testout_422_ifast_opt.jpg
# CC: YCC->RGB SAMP: fullsize/h2v1 fancy IDCT: ifast ENT: huff
./djpeg -dct fast -outfile testout_422_ifast.ppm testout_422_ifast_opt.jpg
md5/md5cmp $(MD5_PPM_422_IFAST) testout_422_ifast.ppm
rm -f testout_422_ifast.ppm
# CC: YCC->RGB SAMP: h2v1 merged IDCT: ifast ENT: huff
./djpeg -dct fast -nosmooth -outfile testout_422m_ifast.ppm testout_422_ifast_opt.jpg
md5/md5cmp $(MD5_PPM_422M_IFAST) testout_422m_ifast.ppm
rm -f testout_422m_ifast.ppm
if WITH_12BIT
rm -f testout_422_ifast_opt.jpg
else
# CC: YCC->RGB565 SAMP: h2v1 merged IDCT: ifast ENT: huff
./djpeg -dct int -nosmooth -rgb565 -dither none -bmp -outfile testout_422m_ifast_565.bmp testout_422_ifast_opt.jpg
md5/md5cmp $(MD5_BMP_422M_IFAST_565) testout_422m_ifast_565.bmp
rm -f testout_422m_ifast_565.bmp
# CC: YCC->RGB565 (dithered) SAMP: h2v1 merged IDCT: ifast ENT: huff
./djpeg -dct int -nosmooth -rgb565 -bmp -outfile testout_422m_ifast_565D.bmp testout_422_ifast_opt.jpg
md5/md5cmp $(MD5_BMP_422M_IFAST_565D) testout_422m_ifast_565D.bmp
rm -f testout_422m_ifast_565D.bmp testout_422_ifast_opt.jpg
endif
# CC: RGB->YCC SAMP: fullsize/h2v2 FDCT: ifast ENT: prog huff
./cjpeg -revert -sample 2x2 -quality 100 -dct fast -prog -outfile testout_420_q100_ifast_prog.jpg $(srcdir)/testimages/testorig.ppm
md5/md5cmp $(MD5_JPEG_420_IFAST_Q100_PROG) testout_420_q100_ifast_prog.jpg
# CC: YCC->RGB SAMP: fullsize/h2v2 fancy IDCT: ifast ENT: prog huff
./djpeg -dct fast -outfile testout_420_q100_ifast.ppm testout_420_q100_ifast_prog.jpg
md5/md5cmp $(MD5_PPM_420_Q100_IFAST) testout_420_q100_ifast.ppm
rm -f testout_420_q100_ifast.ppm
# CC: YCC->RGB SAMP: h2v2 merged IDCT: ifast ENT: prog huff
./djpeg -dct fast -nosmooth -outfile testout_420m_q100_ifast.ppm testout_420_q100_ifast_prog.jpg
md5/md5cmp $(MD5_PPM_420M_Q100_IFAST) testout_420m_q100_ifast.ppm
rm -f testout_420m_q100_ifast.ppm testout_420_q100_ifast_prog.jpg
# CC: RGB->Gray SAMP: fullsize FDCT: islow ENT: huff
./cjpeg -revert -gray -dct int -outfile testout_gray_islow.jpg $(srcdir)/testimages/testorig.ppm
md5/md5cmp $(MD5_JPEG_GRAY_ISLOW) testout_gray_islow.jpg
# CC: Gray->Gray SAMP: fullsize IDCT: islow ENT: huff
./djpeg -dct int -outfile testout_gray_islow.ppm testout_gray_islow.jpg
md5/md5cmp $(MD5_PPM_GRAY_ISLOW) testout_gray_islow.ppm
rm -f testout_gray_islow.ppm
# CC: Gray->RGB SAMP: fullsize IDCT: islow ENT: huff
./djpeg -dct int -rgb -outfile testout_gray_islow_rgb.ppm testout_gray_islow.jpg
md5/md5cmp $(MD5_PPM_GRAY_ISLOW_RGB) testout_gray_islow_rgb.ppm
rm -f testout_gray_islow_rgb.ppm
if WITH_12BIT
rm -f testout_gray_islow.jpg
else
# CC: Gray->RGB565 SAMP: fullsize IDCT: islow ENT: huff
./djpeg -dct int -rgb565 -dither none -bmp -outfile testout_gray_islow_565.bmp testout_gray_islow.jpg
md5/md5cmp $(MD5_BMP_GRAY_ISLOW_565) testout_gray_islow_565.bmp
rm -f testout_gray_islow_565.bmp
# CC: Gray->RGB565 (dithered) SAMP: fullsize IDCT: islow ENT: huff
./djpeg -dct int -rgb565 -bmp -outfile testout_gray_islow_565D.bmp testout_gray_islow.jpg
md5/md5cmp $(MD5_BMP_GRAY_ISLOW_565D) testout_gray_islow_565D.bmp
rm -f testout_gray_islow_565D.bmp testout_gray_islow.jpg
endif
# CC: RGB->YCC SAMP: fullsize smooth/h2v2 smooth FDCT: islow
# ENT: 2-pass huff
./cjpeg -revert -sample 2x2 -smooth 1 -dct int -opt -outfile testout_420s_ifast_opt.jpg $(srcdir)/testimages/testorig.ppm
md5/md5cmp $(MD5_JPEG_420S_IFAST_OPT) testout_420s_ifast_opt.jpg
rm -f testout_420s_ifast_opt.jpg
# The output of the floating point tests is not validated by default, because
# the output differs depending on the type of floating point math used, and
# this is only deterministic if the DCT/IDCT are implemented using SIMD
# instructions on a particular platform. Pass one of the following on the make
# command line to validate the floating point tests against one of the expected
# results:
#
# FLOATTEST=sse validate against the expected results from the libjpeg-turbo
# SSE SIMD extensions
# FLOATTEST=32bit validate against the expected results from the C code
# when running on a 32-bit FPU (or when SSE is being used for
# floating point math, which is generally the default with
# x86-64 compilers)
# FLOATTEST=64bit validate against the exepected results from the C code
# when running on a 64-bit FPU
# CC: RGB->YCC SAMP: fullsize/int FDCT: float ENT: prog huff
./cjpeg -revert -sample 3x2 -dct float -prog -outfile testout_3x2_float_prog.jpg $(srcdir)/testimages/testorig.ppm
if [ "${FLOATTEST}" = "sse" ]; then \
md5/md5cmp $(MD5_JPEG_3x2_FLOAT_PROG_SSE) testout_3x2_float_prog.jpg; \
elif [ "${FLOATTEST}" = "32bit" -o "${FLOATTEST}" = "64bit" ]; then \
md5/md5cmp $(MD5_JPEG_3x2_FLOAT_PROG_32BIT) testout_3x2_float_prog.jpg; \
fi
# CC: YCC->RGB SAMP: fullsize/int IDCT: float ENT: prog huff
./djpeg -dct float -outfile testout_3x2_float.ppm testout_3x2_float_prog.jpg
if [ "${FLOATTEST}" = "sse" ]; then \
md5/md5cmp $(MD5_PPM_3x2_FLOAT_SSE) testout_3x2_float.ppm; \
elif [ "${FLOATTEST}" = "32bit" ]; then \
md5/md5cmp $(MD5_PPM_3x2_FLOAT_32BIT) testout_3x2_float.ppm; \
elif [ "${FLOATTEST}" = "64bit" ]; then \
md5/md5cmp $(MD5_PPM_3x2_FLOAT_64BIT) testout_3x2_float.ppm; \
fi
rm -f testout_3x2_float.ppm testout_3x2_float_prog.jpg
# CC: RGB->YCC SAMP: fullsize/int FDCT: ifast ENT: prog huff
./cjpeg -revert -sample 3x2 -dct fast -prog -outfile testout_3x2_ifast_prog.jpg $(srcdir)/testimages/testorig.ppm
md5/md5cmp $(MD5_JPEG_3x2_IFAST_PROG) testout_3x2_ifast_prog.jpg
# CC: YCC->RGB SAMP: fullsize/int IDCT: ifast ENT: prog huff
./djpeg -dct fast -outfile testout_3x2_ifast.ppm testout_3x2_ifast_prog.jpg
md5/md5cmp $(MD5_PPM_3x2_IFAST) testout_3x2_ifast.ppm
rm -f testout_3x2_ifast.ppm testout_3x2_ifast_prog.jpg
if WITH_ARITH_ENC
# CC: YCC->RGB SAMP: fullsize/h2v2 FDCT: islow ENT: arith
./cjpeg -revert -dct int -arithmetic -outfile testout_420_islow_ari.jpg $(srcdir)/testimages/testorig.ppm
md5/md5cmp $(MD5_JPEG_420_ISLOW_ARI) testout_420_islow_ari.jpg
rm -f testout_420_islow_ari.jpg
./jpegtran -revert -arithmetic -outfile testout_420_islow_ari.jpg $(srcdir)/testimages/testimgint.jpg
md5/md5cmp $(MD5_JPEG_420_ISLOW_ARI) testout_420_islow_ari.jpg
rm -f testout_420_islow_ari.jpg
# CC: YCC->RGB SAMP: fullsize FDCT: islow ENT: prog arith
./cjpeg -revert -sample 1x1 -dct int -prog -arithmetic -outfile testout_444_islow_progari.jpg $(srcdir)/testimages/testorig.ppm
md5/md5cmp $(MD5_JPEG_444_ISLOW_PROGARI) testout_444_islow_progari.jpg
rm -f testout_444_islow_progari.jpg
endif
if WITH_ARITH_DEC
# CC: RGB->YCC SAMP: h2v2 merged IDCT: ifast ENT: arith
./djpeg -fast -ppm -outfile testout_420m_ifast_ari.ppm $(srcdir)/testimages/testimgari.jpg
md5/md5cmp $(MD5_PPM_420M_IFAST_ARI) testout_420m_ifast_ari.ppm
rm -f testout_420m_ifast_ari.ppm
./jpegtran -revert -outfile testout_420_islow.jpg $(srcdir)/testimages/testimgari.jpg
md5/md5cmp $(MD5_JPEG_420_ISLOW) testout_420_islow.jpg
rm -f testout_420_islow.jpg
endif
# CC: YCC->RGB SAMP: h2v2 merged IDCT: 16x16 islow ENT: huff
./djpeg -dct int -scale 2/1 -nosmooth -ppm -outfile testout_420m_islow_2_1.ppm $(srcdir)/testimages/$(TESTORIG)
md5/md5cmp $(MD5_PPM_420M_ISLOW_2_1) testout_420m_islow_2_1.ppm
rm -f testout_420m_islow_2_1.ppm
# CC: YCC->RGB SAMP: h2v2 merged IDCT: 15x15 islow ENT: huff
./djpeg -dct int -scale 15/8 -nosmooth -ppm -outfile testout_420m_islow_15_8.ppm $(srcdir)/testimages/$(TESTORIG)
md5/md5cmp $(MD5_PPM_420M_ISLOW_15_8) testout_420m_islow_15_8.ppm
rm -f testout_420m_islow_15_8.ppm
# CC: YCC->RGB SAMP: h2v2 merged IDCT: 13x13 islow ENT: huff
./djpeg -dct int -scale 13/8 -nosmooth -ppm -outfile testout_420m_islow_13_8.ppm $(srcdir)/testimages/$(TESTORIG)
md5/md5cmp $(MD5_PPM_420M_ISLOW_13_8) testout_420m_islow_13_8.ppm
rm -f testout_420m_islow_13_8.ppm
# CC: YCC->RGB SAMP: h2v2 merged IDCT: 11x11 islow ENT: huff
./djpeg -dct int -scale 11/8 -nosmooth -ppm -outfile testout_420m_islow_11_8.ppm $(srcdir)/testimages/$(TESTORIG)
md5/md5cmp $(MD5_PPM_420M_ISLOW_11_8) testout_420m_islow_11_8.ppm
rm -f testout_420m_islow_11_8.ppm
# CC: YCC->RGB SAMP: h2v2 merged IDCT: 9x9 islow ENT: huff
./djpeg -dct int -scale 9/8 -nosmooth -ppm -outfile testout_420m_islow_9_8.ppm $(srcdir)/testimages/$(TESTORIG)
md5/md5cmp $(MD5_PPM_420M_ISLOW_9_8) testout_420m_islow_9_8.ppm
rm -f testout_420m_islow_9_8.ppm
# CC: YCC->RGB SAMP: h2v2 merged IDCT: 7x7 islow/14x14 islow ENT: huff
./djpeg -dct int -scale 7/8 -nosmooth -ppm -outfile testout_420m_islow_7_8.ppm $(srcdir)/testimages/$(TESTORIG)
md5/md5cmp $(MD5_PPM_420M_ISLOW_7_8) testout_420m_islow_7_8.ppm
rm -f testout_420m_islow_7_8.ppm
# CC: YCC->RGB SAMP: h2v2 merged IDCT: 6x6 islow/12x12 islow ENT: huff
./djpeg -dct int -scale 3/4 -nosmooth -ppm -outfile testout_420m_islow_3_4.ppm $(srcdir)/testimages/$(TESTORIG)
md5/md5cmp $(MD5_PPM_420M_ISLOW_3_4) testout_420m_islow_3_4.ppm
rm -f testout_420m_islow_3_4.ppm
# CC: YCC->RGB SAMP: h2v2 merged IDCT: 5x5 islow/10x10 islow ENT: huff
./djpeg -dct int -scale 5/8 -nosmooth -ppm -outfile testout_420m_islow_5_8.ppm $(srcdir)/testimages/$(TESTORIG)
md5/md5cmp $(MD5_PPM_420M_ISLOW_5_8) testout_420m_islow_5_8.ppm
rm -f testout_420m_islow_5_8.ppm
# CC: YCC->RGB SAMP: h2v2 merged IDCT: 4x4 islow/8x8 islow ENT: huff
./djpeg -dct int -scale 1/2 -nosmooth -ppm -outfile testout_420m_islow_1_2.ppm $(srcdir)/testimages/$(TESTORIG)
md5/md5cmp $(MD5_PPM_420M_ISLOW_1_2) testout_420m_islow_1_2.ppm
rm -f testout_420m_islow_1_2.ppm
# CC: YCC->RGB SAMP: h2v2 merged IDCT: 3x3 islow/6x6 islow ENT: huff
./djpeg -dct int -scale 3/8 -nosmooth -ppm -outfile testout_420m_islow_3_8.ppm $(srcdir)/testimages/$(TESTORIG)
md5/md5cmp $(MD5_PPM_420M_ISLOW_3_8) testout_420m_islow_3_8.ppm
rm -f testout_420m_islow_3_8.ppm
# CC: YCC->RGB SAMP: h2v2 merged IDCT: 2x2 islow/4x4 islow ENT: huff
./djpeg -dct int -scale 1/4 -nosmooth -ppm -outfile testout_420m_islow_1_4.ppm $(srcdir)/testimages/$(TESTORIG)
md5/md5cmp $(MD5_PPM_420M_ISLOW_1_4) testout_420m_islow_1_4.ppm
rm -f testout_420m_islow_1_4.ppm
# CC: YCC->RGB SAMP: h2v2 merged IDCT: 1x1 islow/2x2 islow ENT: huff
./djpeg -dct int -scale 1/8 -nosmooth -ppm -outfile testout_420m_islow_1_8.ppm $(srcdir)/testimages/$(TESTORIG)
md5/md5cmp $(MD5_PPM_420M_ISLOW_1_8) testout_420m_islow_1_8.ppm
rm -f testout_420m_islow_1_8.ppm
if WITH_12BIT
else
# CC: YCC->RGB (dithered) SAMP: h2v2 fancy IDCT: islow ENT: huff
./djpeg -dct int -colors 256 -bmp -outfile testout_420_islow_256.bmp $(srcdir)/testimages/$(TESTORIG)
md5/md5cmp $(MD5_BMP_420_ISLOW_256) testout_420_islow_256.bmp
rm -f testout_420_islow_256.bmp
# CC: YCC->RGB565 SAMP: h2v2 fancy IDCT: islow ENT: huff
./djpeg -dct int -rgb565 -dither none -bmp -outfile testout_420_islow_565.bmp $(srcdir)/testimages/$(TESTORIG)
md5/md5cmp $(MD5_BMP_420_ISLOW_565) testout_420_islow_565.bmp
rm -f testout_420_islow_565.bmp
# CC: YCC->RGB565 (dithered) SAMP: h2v2 fancy IDCT: islow ENT: huff
./djpeg -dct int -rgb565 -bmp -outfile testout_420_islow_565D.bmp $(srcdir)/testimages/$(TESTORIG)
md5/md5cmp $(MD5_BMP_420_ISLOW_565D) testout_420_islow_565D.bmp
rm -f testout_420_islow_565D.bmp
# CC: YCC->RGB565 SAMP: h2v2 merged IDCT: islow ENT: huff
./djpeg -dct int -nosmooth -rgb565 -dither none -bmp -outfile testout_420m_islow_565.bmp $(srcdir)/testimages/$(TESTORIG)
md5/md5cmp $(MD5_BMP_420M_ISLOW_565) testout_420m_islow_565.bmp
rm -f testout_420m_islow_565.bmp
# CC: YCC->RGB565 (dithered) SAMP: h2v2 merged IDCT: islow ENT: huff
./djpeg -dct int -nosmooth -rgb565 -bmp -outfile testout_420m_islow_565D.bmp $(srcdir)/testimages/$(TESTORIG)
md5/md5cmp $(MD5_BMP_420M_ISLOW_565D) testout_420m_islow_565D.bmp
rm -f testout_420m_islow_565D.bmp
endif
# Partial decode tests. These tests are designed to cover all of the possible
# code paths in jpeg_skip_scanlines().
# Context rows: Yes Intra-iMCU row: Yes iMCU row prefetch: No ENT: huff
./djpeg -dct int -skip 15,31 -ppm -outfile testout_420_islow_skip15,31.ppm $(srcdir)/testimages/$(TESTORIG)
md5/md5cmp $(MD5_PPM_420_ISLOW_SKIP15_31) testout_420_islow_skip15,31.ppm
rm -f testout_420_islow_skip15,31.ppm
# Context rows: Yes Intra-iMCU row: No iMCU row prefetch: Yes ENT: arith
if WITH_ARITH_DEC
./djpeg -dct int -skip 16,139 -ppm -outfile testout_420_islow_ari_skip16,139.ppm $(srcdir)/testimages/testimgari.jpg
md5/md5cmp $(MD5_PPM_420_ISLOW_ARI_SKIP16_139) testout_420_islow_ari_skip16,139.ppm
rm -f testout_420_islow_ari_skip16,139.ppm
endif
# Context rows: Yes Intra-iMCU row: No iMCU row prefetch: No ENT: prog huff
./cjpeg -revert -dct int -prog -outfile testout_420_islow_prog.jpg $(srcdir)/testimages/testorig.ppm
./djpeg -dct int -crop 62x62+71+71 -ppm -outfile testout_420_islow_prog_crop62x62,71,71.ppm testout_420_islow_prog.jpg
md5/md5cmp $(MD5_PPM_420_ISLOW_PROG_CROP62x62_71_71) testout_420_islow_prog_crop62x62,71,71.ppm
rm -f testout_420_islow_prog_crop62x62,71,71.ppm testout_420_islow_prog.jpg
# Context rows: Yes Intra-iMCU row: No iMCU row prefetch: No ENT: arith
if WITH_ARITH_DEC
./djpeg -dct int -crop 53x53+4+4 -ppm -outfile testout_420_islow_ari_crop53x53,4,4.ppm $(srcdir)/testimages/testimgari.jpg
md5/md5cmp $(MD5_PPM_420_ISLOW_ARI_CROP53x53_4_4) testout_420_islow_ari_crop53x53,4,4.ppm
rm -f testout_420_islow_ari_crop53x53,4,4.ppm
endif
# Context rows: No Intra-iMCU row: Yes ENT: huff
./cjpeg -revert -dct int -sample 1x1 -outfile testout_444_islow.jpg $(srcdir)/testimages/testorig.ppm
./djpeg -dct int -skip 1,6 -ppm -outfile testout_444_islow_skip1,6.ppm testout_444_islow.jpg
md5/md5cmp $(MD5_PPM_444_ISLOW_SKIP1_6) testout_444_islow_skip1,6.ppm
rm -f testout_444_islow_skip1,6.ppm testout_444_islow.jpg
# Context rows: No Intra-iMCU row: No ENT: prog huff
./cjpeg -revert -dct int -prog -sample 1x1 -outfile testout_444_islow_prog.jpg $(srcdir)/testimages/testorig.ppm
./djpeg -dct int -crop 98x98+13+13 -ppm -outfile testout_444_islow_prog_crop98x98,13,13.ppm testout_444_islow_prog.jpg
md5/md5cmp $(MD5_PPM_444_ISLOW_PROG_CROP98x98_13_13) testout_444_islow_prog_crop98x98,13,13.ppm
rm -f testout_444_islow_prog_crop98x98,13,13.ppm testout_444_islow_prog.jpg
# Context rows: No Intra-iMCU row: No ENT: arith
if WITH_ARITH_ENC
./cjpeg -revert -dct int -arithmetic -sample 1x1 -outfile testout_444_islow_ari.jpg $(srcdir)/testimages/testorig.ppm
if WITH_ARITH_DEC
./djpeg -dct int -crop 37x37+0+0 -ppm -outfile testout_444_islow_ari_crop37x37,0,0.ppm testout_444_islow_ari.jpg
md5/md5cmp $(MD5_PPM_444_ISLOW_ARI_CROP37x37_0_0) testout_444_islow_ari_crop37x37,0,0.ppm
rm -f testout_444_islow_ari_crop37x37,0,0.ppm
endif
rm -f testout_444_islow_ari.jpg
endif
./jpegtran -revert -crop 120x90+20+50 -transpose -perfect -outfile testout_crop.jpg $(srcdir)/testimages/$(TESTORIG)
md5/md5cmp $(MD5_JPEG_CROP) testout_crop.jpg
rm -f testout_crop.jpg
echo GREAT SUCCESS!
testclean:
rm -f testout*
rm -f *_GRAY_*.bmp
rm -f *_GRAY_*.png
rm -f *_GRAY_*.ppm
rm -f *_GRAY_*.jpg
rm -f *_GRAY.yuv
rm -f *_420_*.bmp
rm -f *_420_*.png
rm -f *_420_*.ppm
rm -f *_420_*.jpg
rm -f *_420.yuv
rm -f *_422_*.bmp
rm -f *_422_*.png
rm -f *_422_*.ppm
rm -f *_422_*.jpg
rm -f *_422.yuv
rm -f *_444_*.bmp
rm -f *_444_*.png
rm -f *_444_*.ppm
rm -f *_444_*.jpg
rm -f *_444.yuv
rm -f *_440_*.bmp
rm -f *_440_*.png
rm -f *_440_*.ppm
rm -f *_440_*.jpg
rm -f *_440.yuv
rm -f *_411_*.bmp
rm -f *_411_*.png
rm -f *_411_*.ppm
rm -f *_411_*.jpg
rm -f *_411.yuv
tjtest:
sh ./tjbenchtest
sh ./tjbenchtest -alloc
sh ./tjbenchtest -yuv
sh ./tjbenchtest -yuv -alloc
if WITH_JAVA
sh ./tjbenchtest.java
sh ./tjbenchtest.java -yuv
endif
pkgscripts/mozjpeg.spec: pkgscripts/mozjpeg.spec.tmpl
cat pkgscripts/mozjpeg.spec.tmpl | sed s@%{__prefix}@$(prefix)@g | \
sed s@%{__bindir}@$(bindir)@g | sed s@%{__datadir}@$(datadir)@g | \
sed s@%{__docdir}@$(docdir)@g | sed s@%{__includedir}@$(includedir)@g | \
sed s@%{__libdir}@$(libdir)@g | sed s@%{__mandir}@$(mandir)@g \
> pkgscripts/mozjpeg.spec
rpm: all pkgscripts/mozjpeg.spec
TMPDIR=`mktemp -d /tmp/${PACKAGE_NAME}-build.XXXXXX`; \
mkdir -p $$TMPDIR/RPMS; \
ln -fs `pwd` $$TMPDIR/BUILD; \
rm -f ${PKGNAME}-${VERSION}.${RPMARCH}.rpm; \
rpmbuild -bb --define "_blddir $$TMPDIR/buildroot" \
--define "_topdir $$TMPDIR" \
--target ${RPMARCH} pkgscripts/mozjpeg.spec; \
cp $$TMPDIR/RPMS/${RPMARCH}/${PKGNAME}-${VERSION}-${BUILD}.${RPMARCH}.rpm \
${PKGNAME}-${VERSION}.${RPMARCH}.rpm; \
rm -rf $$TMPDIR
srpm: dist-gzip pkgscripts/mozjpeg.spec
TMPDIR=`mktemp -d /tmp/${PACKAGE_NAME}-build.XXXXXX`; \
mkdir -p $$TMPDIR/RPMS; \
mkdir -p $$TMPDIR/SRPMS; \
mkdir -p $$TMPDIR/BUILD; \
mkdir -p $$TMPDIR/SOURCES; \
mkdir -p $$TMPDIR/SPECS; \
rm -f ${PKGNAME}-${VERSION}.src.rpm; \
cp ${PACKAGE_NAME}-${VERSION}.tar.gz $$TMPDIR/SOURCES; \
cat pkgscripts/mozjpeg.spec | sed s/%{_blddir}/%{_tmppath}/g \
| sed s/#--\>//g \
> $$TMPDIR/SPECS/mozjpeg.spec; \
rpmbuild -bs --define "_topdir $$TMPDIR" $$TMPDIR/SPECS/mozjpeg.spec; \
cp $$TMPDIR/SRPMS/${PKGNAME}-${VERSION}-${BUILD}.src.rpm \
${PKGNAME}-${VERSION}.src.rpm; \
rm -rf $$TMPDIR
pkgscripts/makedpkg: pkgscripts/makedpkg.tmpl
cat pkgscripts/makedpkg.tmpl | sed s@%{__prefix}@$(prefix)@g | \
sed s@%{__docdir}@$(docdir)@g | sed s@%{__libdir}@$(libdir)@g \
> pkgscripts/makedpkg
deb: all pkgscripts/makedpkg
sh pkgscripts/makedpkg
pkgscripts/uninstall: pkgscripts/uninstall.tmpl
cat pkgscripts/uninstall.tmpl | sed s@%{__prefix}@$(prefix)@g | \
sed s@%{__bindir}@$(bindir)@g | sed s@%{__datadir}@$(datadir)@g | \
sed s@%{__includedir}@$(includedir)@g | sed s@%{__libdir}@$(libdir)@g | \
sed s@%{__mandir}@$(mandir)@g > pkgscripts/uninstall
pkgscripts/makemacpkg: pkgscripts/makemacpkg.tmpl
cat pkgscripts/makemacpkg.tmpl | sed s@%{__prefix}@$(prefix)@g | \
sed s@%{__bindir}@$(bindir)@g | sed s@%{__docdir}@$(docdir)@g | \
sed s@%{__libdir}@$(libdir)@g > pkgscripts/makemacpkg
if X86_64
udmg: all pkgscripts/makemacpkg pkgscripts/uninstall
sh pkgscripts/makemacpkg -build32 ${BUILDDIR32}
iosdmg: all pkgscripts/makemacpkg pkgscripts/uninstall
sh pkgscripts/makemacpkg -build32 ${BUILDDIR32} -buildarmv6 ${BUILDDIRARMV6} -buildarmv7 ${BUILDDIRARMV7} -buildarmv7s ${BUILDDIRARMV7S} -buildarmv8 ${BUILDDIRARMV8} -lipo "${LIPO}"
else
iosdmg: all pkgscripts/makemacpkg pkgscripts/uninstall
sh pkgscripts/makemacpkg -buildarmv6 ${BUILDDIRARMV6} -buildarmv7 ${BUILDDIRARMV7} -buildarmv7s ${BUILDDIRARMV7S} -buildarmv8 ${BUILDDIRARMV8} -lipo "${LIPO}"
endif
dmg: all pkgscripts/makemacpkg pkgscripts/uninstall
sh pkgscripts/makemacpkg
pkgscripts/makecygwinpkg: pkgscripts/makecygwinpkg.tmpl
cat pkgscripts/makecygwinpkg.tmpl | sed s@%{__prefix}@$(prefix)@g | \
sed s@%{__docdir}@$(docdir)@g | sed s@%{__libdir}@$(libdir)@g \
> pkgscripts/makecygwinpkg
cygwinpkg: all pkgscripts/makecygwinpkg
sh pkgscripts/makecygwinpkg

View File

@@ -24,7 +24,7 @@ mozjpeg's implementation of the libjpeg API includes an extensibility framework
that allows new features to be added without modifying the transparent libjpeg
compress/decompress structures (which would break backward ABI compatibility.)
Extension parameters are placed into the opaque jpeg_comp_master structure, and
a set of accessor functions and globally unique tokens allows for
a set of accessor functions and globally unique tokens allows for
getting/setting those parameters without directly accessing the structure.
Currently, only the accessor functions necessary to support the mozjpeg
@@ -185,7 +185,7 @@ Integer Extension Parameters Supported by mozjpeg
8 = Table from: An Improved Detection Model for DCT Coefficient Quantization
(1993) Peterson, Ahumada and Watson
* JINT_DC_SCAN_OPT_MODE (default: 1)
* JINT_DC_SCAN_OPT_MODE (default: 0)
Specifies the DC scan optimization mode. The following options are
available:
0 = One scan for all components

View File

@@ -1,13 +1,14 @@
Background
==========
libjpeg-turbo is a JPEG image codec that uses SIMD instructions (MMX, SSE2,
NEON, AltiVec) to accelerate baseline JPEG compression and decompression on
x86, x86-64, ARM, and PowerPC systems. On such systems, libjpeg-turbo is
generally 2-6x as fast as libjpeg, all else being equal. On other types of
systems, libjpeg-turbo can still outperform libjpeg by a significant amount, by
virtue of its highly-optimized Huffman coding routines. In many cases, the
performance of libjpeg-turbo rivals that of proprietary high-speed JPEG codecs.
libjpeg-turbo is a JPEG image codec that uses SIMD instructions to accelerate
baseline JPEG compression and decompression on x86, x86-64, Arm, PowerPC, and
MIPS systems, as well as progressive JPEG compression on x86, x86-64, and Arm
systems. On such systems, libjpeg-turbo is generally 2-6x as fast as libjpeg,
all else being equal. On other types of systems, libjpeg-turbo can still
outperform libjpeg by a significant amount, by virtue of its highly-optimized
Huffman coding routines. In many cases, the performance of libjpeg-turbo
rivals that of proprietary high-speed JPEG codecs.
libjpeg-turbo implements both the traditional libjpeg API as well as the less
powerful but more straightforward TurboJPEG API. libjpeg-turbo also features
@@ -20,7 +21,26 @@ derivative of libjpeg v6b developed by Miyasaka Masaru. The TigerVNC and
VirtualGL projects made numerous enhancements to the codec in 2009, and in
early 2010, libjpeg-turbo spun off into an independent project, with the goal
of making high-speed JPEG compression/decompression technology available to a
broader range of users and developers.
broader range of users and developers. libjpeg-turbo is an ISO/IEC and ITU-T
reference implementation of the JPEG standard.
More information about libjpeg-turbo can be found at
<https://libjpeg-turbo.org>.
Funding
=======
libjpeg-turbo is an independent open source project, but we rely on patronage
and funded development in order to maintain that independence. The easiest way
to ensure that libjpeg-turbo remains community-focused and free of any one
organization's agenda is to
[sponsor our project through GitHub](https://github.com/sponsors/libjpeg-turbo).
All sponsorship money goes directly toward funding the labor necessary to
maintain libjpeg-turbo, support the user community, and implement bug fixes and
strategically important features.
[![Sponsor libjpeg-turbo](https://img.shields.io/github/sponsors/libjpeg-turbo?label=Sponsor&logo=GitHub)](https://github.com/sponsors/libjpeg-turbo)
License
@@ -42,21 +62,26 @@ Using libjpeg-turbo
libjpeg-turbo includes two APIs that can be used to compress and decompress
JPEG images:
- **TurboJPEG API**
- **TurboJPEG API**<br>
This API provides an easy-to-use interface for compressing and decompressing
JPEG images in memory. It also provides some functionality that would not be
straightforward to achieve using the underlying libjpeg API, such as
generating planar YUV images and performing multiple simultaneous lossless
transforms on an image. The Java interface for libjpeg-turbo is written on
top of the TurboJPEG API.
top of the TurboJPEG API. The TurboJPEG API is recommended for first-time
users of libjpeg-turbo. Refer to [tjexample.c](tjexample.c) and
[TJExample.java](java/TJExample.java) for examples of its usage and to
<https://libjpeg-turbo.org/Documentation/Documentation> for API
documentation.
- **libjpeg API**
- **libjpeg API**<br>
This is the de facto industry-standard API for compressing and decompressing
JPEG images. It is more difficult to use than the TurboJPEG API but also
more powerful. The libjpeg API implementation in libjpeg-turbo is both
API/ABI-compatible and mathematically compatible with libjpeg v6b. It can
also optionally be configured to be API/ABI-compatible with libjpeg v7 and v8
(see below.)
(see below.) Refer to [cjpeg.c](cjpeg.c) and [djpeg.c](djpeg.c) for examples
of its usage and to [libjpeg.txt](libjpeg.txt) for API documentation.
There is no significant performance advantage to either API when both are used
to perform similar operations.
@@ -130,28 +155,27 @@ without recompiling. libjpeg-turbo does not claim to support all of the
libjpeg v7+ features, nor to produce identical output to libjpeg v7+ in all
cases (see below.)
By passing an argument of `--with-jpeg7` or `--with-jpeg8` to `configure`, or
an argument of `-DWITH_JPEG7=1` or `-DWITH_JPEG8=1` to `cmake`, you can build a
version of libjpeg-turbo that emulates the libjpeg v7 or v8 ABI, so that
programs that are built against libjpeg v7 or v8 can be run with libjpeg-turbo.
The following section describes which libjpeg v7+ features are supported and
which aren't.
By passing an argument of `-DWITH_JPEG7=1` or `-DWITH_JPEG8=1` to `cmake`, you
can build a version of libjpeg-turbo that emulates the libjpeg v7 or v8 ABI, so
that programs that are built against libjpeg v7 or v8 can be run with
libjpeg-turbo. The following section describes which libjpeg v7+ features are
supported and which aren't.
### Support for libjpeg v7 and v8 Features
#### Fully supported
- **libjpeg: IDCT scaling extensions in decompressor**
- **libjpeg API: IDCT scaling extensions in decompressor**<br>
libjpeg-turbo supports IDCT scaling with scaling factors of 1/8, 1/4, 3/8,
1/2, 5/8, 3/4, 7/8, 9/8, 5/4, 11/8, 3/2, 13/8, 7/4, 15/8, and 2/1 (only 1/4
and 1/2 are SIMD-accelerated.)
- **libjpeg: Arithmetic coding**
- **libjpeg API: Arithmetic coding**
- **libjpeg: In-memory source and destination managers**
- **libjpeg API: In-memory source and destination managers**<br>
See notes below.
- **cjpeg: Separate quality settings for luminance and chrominance**
- **cjpeg: Separate quality settings for luminance and chrominance**<br>
Note that the libpjeg v7+ API was extended to accommodate this feature only
for convenience purposes. It has always been possible to implement this
feature with libjpeg v6b (see rdswitch.c for an example.)
@@ -175,19 +199,19 @@ which aren't.
NOTE: As of this writing, extensive research has been conducted into the
usefulness of DCT scaling as a means of data reduction and SmartScale as a
means of quality improvement. The reader is invited to peruse the research at
<http://www.libjpeg-turbo.org/About/SmartScale> and draw his/her own conclusions,
means of quality improvement. Readers are invited to peruse the research at
<https://libjpeg-turbo.org/About/SmartScale> and draw their own conclusions,
but it is the general belief of our project that these features have not
demonstrated sufficient usefulness to justify inclusion in libjpeg-turbo.
- **libjpeg: DCT scaling in compressor**
- **libjpeg API: DCT scaling in compressor**<br>
`cinfo.scale_num` and `cinfo.scale_denom` are silently ignored.
There is no technical reason why DCT scaling could not be supported when
emulating the libjpeg v7+ API/ABI, but without the SmartScale extension (see
below), only scaling factors of 1/2, 8/15, 4/7, 8/13, 2/3, 8/11, 4/5, and
8/9 would be available, which is of limited usefulness.
- **libjpeg: SmartScale**
- **libjpeg API: SmartScale**<br>
`cinfo.block_size` is silently ignored.
SmartScale is an extension to the JPEG format that allows for DCT block
sizes other than 8x8. Providing support for this new format would be
@@ -200,15 +224,15 @@ demonstrated sufficient usefulness to justify inclusion in libjpeg-turbo.
interest in providing this feature would be as a means of supporting
additional DCT scaling factors.
- **libjpeg: Fancy downsampling in compressor**
- **libjpeg API: Fancy downsampling in compressor**<br>
`cinfo.do_fancy_downsampling` is silently ignored.
This requires the DCT scaling feature, which is not supported.
- **jpegtran: Scaling**
- **jpegtran: Scaling**<br>
This requires both the DCT scaling and SmartScale features, which are not
supported.
- **Lossless RGB JPEG files**
- **Lossless RGB JPEG files**<br>
This requires the SmartScale feature, which is not supported.
### What About libjpeg v9?
@@ -226,7 +250,7 @@ generally accomplish anything that can't already be accomplished better with
existing, standard lossless formats. Therefore, at this time it is our belief
that there is not sufficient technical justification for software projects to
upgrade from libjpeg v8 to libjpeg v9, and thus there is not sufficient
echnical justification for us to emulate the libjpeg v9 ABI.
technical justification for us to emulate the libjpeg v9 ABI.
In-Memory Source/Destination Managers
-------------------------------------
@@ -241,17 +265,6 @@ programs that need them, without breaking ABI compatibility for programs that
don't, and it allows those functions to be provided in the "official"
libjpeg-turbo binaries.
Those who are concerned about maintaining strict conformance with the libjpeg
v6b or v7 API can pass an argument of `--without-mem-srcdst` to `configure` or
an argument of `-DWITH_MEM_SRCDST=0` to `cmake` prior to building
libjpeg-turbo. This will restore the pre-1.3 behavior, in which
`jpeg_mem_src()` and `jpeg_mem_dest()` are only included when emulating the
libjpeg v8 API/ABI.
On Un*x systems, including the in-memory source/destination managers changes
the dynamic library version from 62.0.0 to 62.1.0 if using libjpeg v6b API/ABI
emulation and from 7.0.0 to 7.1.0 if using libjpeg v7 API/ABI emulation.
Note that, on most Un*x systems, the dynamic linker will not look for a
function in a library until that function is actually used. Thus, if a program
is built against libjpeg-turbo 1.3+ and uses `jpeg_mem_src()` or
@@ -271,29 +284,35 @@ Mathematical Compatibility
==========================
For the most part, libjpeg-turbo should produce identical output to libjpeg
v6b. The one exception to this is when using the floating point DCT/IDCT, in
which case the outputs of libjpeg v6b and libjpeg-turbo can differ for the
following reasons:
v6b. There are two exceptions:
- The SSE/SSE2 floating point DCT implementation in libjpeg-turbo is ever so
slightly more accurate than the implementation in libjpeg v6b, but not by
any amount perceptible to human vision (generally in the range of 0.01 to
0.08 dB gain in PNSR.)
1. When decompressing a JPEG image that uses 4:4:0 chrominance subsampling, the
outputs of libjpeg v6b and libjpeg-turbo can differ because libjpeg-turbo
implements a "fancy" (smooth) 4:4:0 upsampling algorithm and libjpeg did not.
- When not using the SIMD extensions, libjpeg-turbo uses the more accurate
(and slightly faster) floating point IDCT algorithm introduced in libjpeg
v8a as opposed to the algorithm used in libjpeg v6b. It should be noted,
however, that this algorithm basically brings the accuracy of the floating
point IDCT in line with the accuracy of the slow integer IDCT. The floating
point DCT/IDCT algorithms are mainly a legacy feature, and they do not
produce significantly more accuracy than the slow integer algorithms (to put
numbers on this, the typical difference in PNSR between the two algorithms
is less than 0.10 dB, whereas changing the quality level by 1 in the upper
range of the quality scale is typically more like a 1.0 dB difference.)
2. When using the floating point DCT/IDCT, the outputs of libjpeg v6b and
libjpeg-turbo can differ for the following reasons:
- If the floating point algorithms in libjpeg-turbo are not implemented using
SIMD instructions on a particular platform, then the accuracy of the
floating point DCT/IDCT can depend on the compiler settings.
- The SSE/SSE2 floating point DCT implementation in libjpeg-turbo is ever
so slightly more accurate than the implementation in libjpeg v6b, but not
by any amount perceptible to human vision (generally in the range of 0.01
to 0.08 dB gain in PNSR.)
- When not using the SIMD extensions, libjpeg-turbo uses the more accurate
(and slightly faster) floating point IDCT algorithm introduced in libjpeg
v8a as opposed to the algorithm used in libjpeg v6b. It should be noted,
however, that this algorithm basically brings the accuracy of the
floating point IDCT in line with the accuracy of the accurate integer
IDCT. The floating point DCT/IDCT algorithms are mainly a legacy
feature, and they do not produce significantly more accuracy than the
accurate integer algorithms. (To put numbers on this, the typical
difference in PNSR between the two algorithms is less than 0.10 dB,
whereas changing the quality level by 1 in the upper range of the quality
scale is typically more like a 1.0 dB difference.)
- If the floating point algorithms in libjpeg-turbo are not implemented
using SIMD instructions on a particular platform, then the accuracy of
the floating point DCT/IDCT can depend on the compiler settings.
While libjpeg-turbo does emulate the libjpeg v8 API/ABI, under the hood it is
still using the same algorithms as libjpeg v6b, so there are several specific
@@ -326,7 +345,7 @@ in a way that makes the rest of the libjpeg infrastructure happy, so it is
necessary to use the slow Huffman decoder when decompressing a JPEG image that
has restart markers. This can cause the decompression performance to drop by
as much as 20%, but the performance will still be much greater than that of
libjpeg. Many consumer packages, such as PhotoShop, use restart markers when
libjpeg. Many consumer packages, such as Photoshop, use restart markers when
generating JPEG images, so images generated by those programs will experience
this issue.
@@ -337,6 +356,17 @@ The algorithm used by the SIMD-accelerated quantization function cannot produce
correct results whenever the fast integer forward DCT is used along with a JPEG
quality of 98-100. Thus, libjpeg-turbo must use the non-SIMD quantization
function in those cases. This causes performance to drop by as much as 40%.
It is therefore strongly advised that you use the slow integer forward DCT
It is therefore strongly advised that you use the accurate integer forward DCT
whenever encoding images with a JPEG quality of 98 or higher.
Memory Debugger Pitfalls
========================
Valgrind and Memory Sanitizer (MSan) can generate false positives
(specifically, incorrect reports of uninitialized memory accesses) when used
with libjpeg-turbo's SIMD extensions. It is generally recommended that the
SIMD extensions be disabled, either by passing an argument of `-DWITH_SIMD=0`
to `cmake` when configuring the build or by setting the environment variable
`JSIMD_FORCENONE` to `1` at run time, when testing libjpeg-turbo with Valgrind,
MSan, or other memory debuggers.

View File

@@ -68,17 +68,17 @@ other abrupt features may not compress well with JPEG, and a higher JPEG
quality may have to be used to avoid visible compression artifacts with such
images.
JPEG is lossy, meaning that the output pixels are not necessarily identical to
the input pixels. However, on photographic content and other "smooth" images,
very good compression ratios can be obtained with no visible compression
artifacts, and extremely high compression ratios are possible if you are
willing to sacrifice image quality (by reducing the "quality" setting in the
compressor.)
JPEG is normally lossy, meaning that the output pixels are not necessarily
identical to the input pixels. However, on photographic content and other
"smooth" images, very good compression ratios can be obtained with no visible
compression artifacts, and extremely high compression ratios are possible if
you are willing to sacrifice image quality (by reducing the "quality" setting
in the compressor.)
This software implements JPEG baseline, extended-sequential, and progressive
compression processes. Provision is made for supporting all variants of these
processes, although some uncommon parameter settings aren't implemented yet.
We have made no provision for supporting the hierarchical or lossless
This software implements JPEG baseline, extended-sequential, progressive, and
lossless compression processes. Provision is made for supporting all variants
of these processes, although some uncommon parameter settings aren't
implemented yet. We have made no provision for supporting the hierarchical
processes defined in the standard.
We provide a set of library routines for reading and writing JPEG image files,
@@ -89,9 +89,9 @@ The library is intended to be reused in other applications.
In order to support file conversion and viewing software, we have included
considerable functionality beyond the bare JPEG coding/decoding capability;
for example, the color quantization modules are not strictly part of JPEG
decoding, but they are essential for output to colormapped file formats or
colormapped displays. These extra functions can be compiled out of the
library if not required for a particular application.
decoding, but they are essential for output to colormapped file formats. These
extra functions can be compiled out of the library if not required for a
particular application.
We have also included "jpegtran", a utility for lossless transcoding between
different JPEG processes, and "rdjpgcom" and "wrjpgcom", two simple
@@ -128,7 +128,7 @@ with respect to this software, its quality, accuracy, merchantability, or
fitness for a particular purpose. This software is provided "AS IS", and you,
its user, assume the entire risk as to its quality and accuracy.
This software is copyright (C) 1991-2016, Thomas G. Lane, Guido Vollbeding.
This software is copyright (C) 1991-2020, Thomas G. Lane, Guido Vollbeding.
All Rights Reserved except as specified below.
Permission is hereby granted to use, copy, modify, and distribute this
@@ -159,25 +159,6 @@ commercial products, provided that all warranty or liability claims are
assumed by the product vendor.
The Unix configuration script "configure" was produced with GNU Autoconf.
It is copyright by the Free Software Foundation but is freely distributable.
The same holds for its supporting scripts (config.guess, config.sub,
ltmain.sh). Another support script, install-sh, is copyright by X Consortium
but is also freely distributable.
The IJG distribution formerly included code to read and write GIF files.
To avoid entanglement with the Unisys LZW patent (now expired), GIF reading
support has been removed altogether, and the GIF writer has been simplified
to produce "uncompressed GIFs". This technique does not use the LZW
algorithm; the resulting GIF files are larger than usual, but are readable
by all standard GIF decoders.
We are required to state that
"The Graphics Interchange Format(c) is the Copyright property of
CompuServe Incorporated. GIF(sm) is a Service Mark property of
CompuServe Incorporated."
REFERENCES
==========
@@ -185,8 +166,8 @@ We recommend reading one or more of these references before trying to
understand the innards of the JPEG software.
The best short technical introduction to the JPEG compression algorithm is
Wallace, Gregory K. "The JPEG Still Picture Compression Standard",
Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44.
Wallace, Gregory K. "The JPEG Still Picture Compression Standard",
Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44.
(Adjacent articles in that issue discuss MPEG motion picture compression,
applications of JPEG, and related topics.) If you don't have the CACM issue
handy, a PDF file containing a revised version of Wallace's article is
@@ -220,21 +201,21 @@ Continuous-tone Still Images, Part 2: Compliance testing" and has document
numbers ISO/IEC IS 10918-2, ITU-T T.83.
The JPEG standard does not specify all details of an interchangeable file
format. For the omitted details we follow the "JFIF" conventions, revision
1.02. JFIF 1.02 has been adopted as an Ecma International Technical Report
and thus received a formal publication status. It is available as a free
download in PDF format from
http://www.ecma-international.org/publications/techreports/E-TR-098.htm.
A PostScript version of the JFIF document is available at
http://www.ijg.org/files/jfif.ps.gz. There is also a plain text version at
http://www.ijg.org/files/jfif.txt.gz, but it is missing the figures.
format. For the omitted details, we follow the "JFIF" conventions, revision
1.02. JFIF version 1 has been adopted as ISO/IEC 10918-5 (05/2013) and
Recommendation ITU-T T.871 (05/2011): Information technology - Digital
compression and coding of continuous-tone still images: JPEG File Interchange
Format (JFIF). It is available as a free download in PDF file format from
https://www.iso.org/standard/54989.html and http://www.itu.int/rec/T-REC-T.871.
A PDF file of the older JFIF 1.02 specification is available at
http://www.w3.org/Graphics/JPEG/jfif3.pdf.
The TIFF 6.0 file format specification can be obtained by FTP from
ftp://ftp.sgi.com/graphics/tiff/TIFF6.ps.gz. The JPEG incorporation scheme
found in the TIFF 6.0 spec of 3-June-92 has a number of serious problems.
IJG does not recommend use of the TIFF 6.0 design (TIFF Compression tag 6).
Instead, we recommend the JPEG design proposed by TIFF Technical Note #2
(Compression tag 7). Copies of this Note can be obtained from
The TIFF 6.0 file format specification can be obtained from
http://mirrors.ctan.org/graphics/tiff/TIFF6.ps.gz. The JPEG incorporation
scheme found in the TIFF 6.0 spec of 3-June-92 has a number of serious
problems. IJG does not recommend use of the TIFF 6.0 design (TIFF Compression
tag 6). Instead, we recommend the JPEG design proposed by TIFF Technical Note
#2 (Compression tag 7). Copies of this Note can be obtained from
http://www.ijg.org/files/. It is expected that the next revision
of the TIFF spec will replace the 6.0 JPEG design with the Note's design.
Although IJG's own code does not support TIFF/JPEG, the free libtiff library
@@ -249,28 +230,26 @@ The most recent released version can always be found there in
directory "files".
The JPEG FAQ (Frequently Asked Questions) article is a source of some
general information about JPEG.
It is available on the World Wide Web at http://www.faqs.org/faqs/jpeg-faq/
and other news.answers archive sites, including the official news.answers
archive at rtfm.mit.edu: ftp://rtfm.mit.edu/pub/usenet/news.answers/jpeg-faq/.
If you don't have Web or FTP access, send e-mail to mail-server@rtfm.mit.edu
with body
send usenet/news.answers/jpeg-faq/part1
send usenet/news.answers/jpeg-faq/part2
general information about JPEG. It is available at
http://www.faqs.org/faqs/jpeg-faq.
FILE FORMAT WARS
================
FILE FORMAT COMPATIBILITY
=========================
The ISO/IEC JTC1/SC29/WG1 standards committee (also known as JPEG, together
with ITU-T SG16) currently promotes different formats containing the name
"JPEG" which are incompatible with original DCT-based JPEG. IJG therefore does
not support these formats (see REFERENCES). Indeed, one of the original
reasons for developing this free software was to help force convergence on
common, interoperable format standards for JPEG files.
Don't use an incompatible file format!
(In any case, our decoder will remain capable of reading existing JPEG
image files indefinitely.)
This software implements ITU T.81 | ISO/IEC 10918 with some extensions from
ITU T.871 | ISO/IEC 10918-5 (JPEG File Interchange Format-- see REFERENCES).
Informally, the term "JPEG image" or "JPEG file" most often refers to JFIF or
a subset thereof, but there are other formats containing the name "JPEG" that
are incompatible with the original JPEG standard or with JFIF (for instance,
JPEG 2000 and JPEG XR). This software therefore does not support these
formats. Indeed, one of the original reasons for developing this free software
was to help force convergence on a common, interoperable format standard for
JPEG files.
JFIF is a minimal or "low end" representation. TIFF/JPEG (TIFF revision 6.0 as
modified by TIFF Technical Note #2) can be used for "high end" applications
that need to record a lot of additional data about an image.
TO DO

View File

@@ -1,15 +1,29 @@
Mozilla JPEG Encoder Project
Mozilla JPEG Encoder Project [![Build Status](https://ci.appveyor.com/api/projects/status/github/mozilla/mozjpeg?branch=master&svg=true)](https://ci.appveyor.com/project/kornel/mozjpeg-4ekrx)
============================
This project's goal is to reduce the size of JPEG files without reducing quality or compatibility with the vast majority of the world's deployed decoders.
MozJPEG improves JPEG compression efficiency achieving higher visual quality and smaller file sizes at the same time. It is compatible with the JPEG standard, and the vast majority of the world's deployed JPEG decoders.
The idea is to reduce transfer times for JPEGs on the Web, thus reducing page load times.
MozJPEG is a patch for [libjpeg-turbo](https://github.com/libjpeg-turbo/libjpeg-turbo). **Please send pull requests to libjpeg-turbo** if the changes aren't specific to newly-added MozJPEG-only compression code. This project aims to keep differences with libjpeg-turbo minimal, so whenever possible, improvements and bug fixes should go there first.
'mozjpeg' is not intended to be a general JPEG library replacement. It makes tradeoffs that are intended to benefit Web use cases and focuses solely on improving encoding. It is best used as part of a Web encoding workflow. For a general JPEG library (e.g. your system libjpeg), especially if you care about decoding, we recommend libjpeg-turbo.
MozJPEG is compatible with the libjpeg API and ABI. It is intended to be a drop-in replacement for libjpeg. MozJPEG is a strict superset of libjpeg-turbo's functionality. All MozJPEG's improvements can be disabled at run time, and in that case it behaves exactly like libjpeg-turbo.
More information:
MozJPEG is meant to be used as a library in graphics programs and image processing tools. We include a demo `cjpeg` command-line tool, but it's not intended for serious use. We encourage authors of graphics programs to use libjpeg's [C API](libjpeg.txt) and link with MozJPEG library instead.
* [Mailing List](https://lists.mozilla.org/listinfo/dev-mozjpeg)</a>
* [Version 3.0 Announcement](https://boomswaggerboom.wordpress.com/2014/12/30/mozjpeg-3-0-released/)
## Features
* Progressive encoding with "jpegrescan" optimization. It can be applied to any JPEG file (with `jpegtran`) to losslessly reduce file size.
* Trellis quantization. When converting other formats to JPEG it maximizes quality/filesize ratio.
* Comes with new quantization table presets, e.g. tuned for high-resolution displays.
* Fully compatible with all web browsers.
* Can be seamlessly integrated into any program that uses the industry-standard libjpeg API. There's no need to write any MozJPEG-specific integration code.
## Releases
* [Latest release](https://github.com/mozilla/mozjpeg/releases/latest)
* [Overview of 3.0 features](https://calendar.perfplanet.com/2014/mozjpeg-3-0/)
* [Version 2.0 Announcement](https://blog.mozilla.org/research/2014/07/15/mozilla-advances-jpeg-encoding-with-mozjpeg-2-0/)
* [Version 1.0 Announcement](https://blog.mozilla.org/research/2014/03/05/introducing-the-mozjpeg-project/)
## Compiling
See [BUILDING](BUILDING.md). MozJPEG is built exactly the same way as libjpeg-turbo, so if you need additional help please consult [libjpeg-turbo documentation](https://libjpeg-turbo.org/).

View File

@@ -1,254 +0,0 @@
# AC_PROG_NASM
# --------------------------
# Check that NASM exists and determine flags
AC_DEFUN([AC_PROG_NASM],[
AC_ARG_VAR(NASM, [NASM command (used to build the x86/x86-64 SIMD code)])
if test "x$NASM" = "x"; then
AC_CHECK_PROGS(NASM, [nasm nasmw yasm])
test -z "$NASM" && AC_MSG_ERROR([no nasm (Netwide Assembler) found])
fi
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
;;
kfreebsd* | freebsd* | netbsd* | openbsd*)
if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
objfmt='BSD-a.out'
else
case "$host_cpu" in
x86_64 | amd64)
objfmt='ELF64'
;;
*)
objfmt='ELF'
;;
esac
fi
;;
solaris* | sunos* | sysv* | sco*)
case "$host_cpu" in
x86_64)
objfmt='ELF64'
;;
*)
objfmt='ELF'
;;
esac
;;
darwin* | rhapsody* | nextstep* | openstep* | macos*)
case "$host_cpu" in
x86_64)
objfmt='Mach-O64'
;;
*)
objfmt='Mach-O'
;;
esac
;;
*)
objfmt='ELF ?'
;;
esac
AC_MSG_RESULT([$objfmt])
if test "$objfmt" = 'ELF ?'; then
objfmt='ELF'
AC_MSG_WARN([unexpected host system. assumed that the format is $objfmt.])
fi
AC_MSG_CHECKING([for object file format specifier (NAFLAGS) ])
case "$objfmt" in
MSOMF) NAFLAGS='-fobj -DOBJ32';;
Win32-COFF) NAFLAGS='-fwin32 -DWIN32';;
Win64-COFF) NAFLAGS='-fwin64 -DWIN64 -D__x86_64__';;
COFF) NAFLAGS='-fcoff -DCOFF';;
a.out) NAFLAGS='-faout -DAOUT';;
BSD-a.out) NAFLAGS='-faoutb -DAOUT';;
ELF) NAFLAGS='-felf -DELF';;
ELF64) NAFLAGS='-felf64 -DELF -D__x86_64__';;
RDF) NAFLAGS='-frdf -DRDF';;
Mach-O) NAFLAGS='-fmacho -DMACHO';;
Mach-O64) NAFLAGS='-fmacho64 -DMACHO -D__x86_64__';;
esac
AC_MSG_RESULT([$NAFLAGS])
AC_SUBST([NAFLAGS])
AC_MSG_CHECKING([whether the assembler ($NASM $NAFLAGS) works])
cat > conftest.asm <<EOF
[%line __oline__ "configure"
section .text
global _main,main
_main:
main: xor eax,eax
ret
]EOF
try_nasm='$NASM $NAFLAGS -o conftest.o conftest.asm'
if AC_TRY_EVAL(try_nasm) && test -s conftest.o; then
AC_MSG_RESULT(yes)
else
echo "configure: failed program was:" >&AC_FD_CC
cat conftest.asm >&AC_FD_CC
rm -rf conftest*
AC_MSG_RESULT(no)
AC_MSG_ERROR([installation or configuration problem: assembler cannot create object files.])
fi
AC_MSG_CHECKING([whether the linker accepts assembler output])
try_nasm='${CC-cc} -o conftest${ac_exeext} $LDFLAGS conftest.o $LIBS 1>&AC_FD_CC'
if AC_TRY_EVAL(try_nasm) && test -s conftest${ac_exeext}; then
rm -rf conftest*
AC_MSG_RESULT(yes)
else
rm -rf conftest*
AC_MSG_RESULT(no)
AC_MSG_ERROR([configuration problem: maybe object file format mismatch.])
fi
])
# AC_CHECK_COMPATIBLE_ARM_ASSEMBLER_IFELSE
# --------------------------
# Test whether the assembler is suitable and supports NEON instructions
AC_DEFUN([AC_CHECK_COMPATIBLE_ARM_ASSEMBLER_IFELSE],[
ac_good_gnu_arm_assembler=no
ac_save_CC="$CC"
ac_save_CFLAGS="$CFLAGS"
CFLAGS="$CCASFLAGS -x assembler-with-cpp"
CC="$CCAS"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
.text
.fpu neon
.arch armv7a
.object_arch armv4
.arm
pld [r0]
vmovn.u16 d0, q0]])], ac_good_gnu_arm_assembler=yes)
ac_use_gas_preprocessor=no
if test "x$ac_good_gnu_arm_assembler" = "xno" ; then
CC="gas-preprocessor.pl $CCAS"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
.text
.fpu neon
.arch armv7a
.object_arch armv4
.arm
pld [r0]
vmovn.u16 d0, q0]])], ac_use_gas_preprocessor=yes)
fi
CFLAGS="$ac_save_CFLAGS"
CC="$ac_save_CC"
if test "x$ac_use_gas_preprocessor" = "xyes" ; then
CCAS="gas-preprocessor.pl $CCAS"
AC_SUBST([CCAS])
ac_good_gnu_arm_assembler=yes
fi
if test "x$ac_good_gnu_arm_assembler" = "xyes" ; then
$1
else
$2
fi
])
# AC_CHECK_COMPATIBLE_MIPSEL_ASSEMBLER_IFELSE
# --------------------------
# Test whether the assembler is suitable and supports MIPS instructions
AC_DEFUN([AC_CHECK_COMPATIBLE_MIPS_ASSEMBLER_IFELSE],[
have_mips_dspr2=no
ac_save_CFLAGS="$CFLAGS"
CFLAGS="$CCASFLAGS -mdspr2"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
int main ()
{
int c = 0, a = 0, b = 0;
__asm__ __volatile__ (
"precr.qb.ph %[c], %[a], %[b] \n\t"
: [c] "=r" (c)
: [a] "r" (a), [b] "r" (b)
);
return c;
}
]])], have_mips_dspr2=yes)
CFLAGS=$ac_save_CFLAGS
if test "x$have_mips_dspr2" = "xyes" ; then
$1
else
$2
fi
])
AC_DEFUN([AC_CHECK_COMPATIBLE_ARM64_ASSEMBLER_IFELSE],[
ac_good_gnu_arm_assembler=no
ac_save_CC="$CC"
ac_save_CFLAGS="$CFLAGS"
CFLAGS="$CCASFLAGS -x assembler-with-cpp"
CC="$CCAS"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
.text
MYVAR .req x0
movi v0.16b, #100
mov MYVAR, #100
.unreq MYVAR]])], ac_good_gnu_arm_assembler=yes)
ac_use_gas_preprocessor=no
if test "x$ac_good_gnu_arm_assembler" = "xno" ; then
CC="gas-preprocessor.pl $CCAS"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
.text
MYVAR .req x0
movi v0.16b, #100
mov MYVAR, #100
.unreq MYVAR]])], ac_use_gas_preprocessor=yes)
fi
CFLAGS="$ac_save_CFLAGS"
CC="$ac_save_CC"
if test "x$ac_use_gas_preprocessor" = "xyes" ; then
CCAS="gas-preprocessor.pl $CCAS"
AC_SUBST([CCAS])
ac_good_gnu_arm_assembler=yes
fi
if test "x$ac_good_gnu_arm_assembler" = "xyes" ; then
$1
else
$2
fi
])

62
appveyor.yml Normal file
View File

@@ -0,0 +1,62 @@
image: Visual Studio 2019
configuration: Release
platform:
- Win32
- x64
install:
- if %PLATFORM% == Win32 (set ARCH=x86)
- if %PLATFORM% == x64 (set ARCH=x64)
## Set up nasm
- choco install nasm
- set PATH=%PATH%;C:\Program Files\NASM
## Set up libpng
- cd C:\Tools\vcpkg
- vcpkg install libpng:%ARCH%-windows
- vcpkg install libpng:%ARCH%-windows-static
before_build:
- cd %APPVEYOR_BUILD_FOLDER%
- nasm -v
- cmake --version
- git describe --always --tags --dirty
- FOR /F %%a in ('git describe --always --tags --dirty') do set GIT_VERSION=%%a
build_script:
## Build shared
- cmake -B shared -A %PLATFORM%
-DENABLE_SHARED=1 -DENABLE_STATIC=0
-DREQUIRE_SIMD=1
-DCMAKE_TOOLCHAIN_FILE=C:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake
- cmake --build shared --config Release
## Build static
- cmake -B static -A %PLATFORM%
-DENABLE_SHARED=0 -DENABLE_STATIC=1
-DREQUIRE_SIMD=1
-DCMAKE_TOOLCHAIN_FILE=C:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake
-DVCPKG_TARGET_TRIPLET=%ARCH%-windows-static
- cmake --build static --config Release
after_build:
- 7z a mozjpeg-%GIT_VERSION%-win-%ARCH%.zip shared/Release static/Release
artifacts:
- path: '*.zip'
cache:
- C:\ProgramData\chocolatey\bin
- C:\ProgramData\chocolatey\lib
- C:\Program Files\NASM
- C:\tools\vcpkg\installed
deploy:
description: 'Automated build using Appveyor'
provider: GitHub
auth_token:
secure: 2Jj47Q5HnaPob9U4yX2t4q4TYTw4JWU6cS56mM12aoRLgfYkZ4gRZPySIzfmTPqC
artifact: /.*\.zip/
on:
APPVEYOR_REPO_TAG: true # deploy on tag push only

334
bmp.c
View File

@@ -1,334 +0,0 @@
/*
* Copyright (C)2011, 2015 D. R. Commander. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the libjpeg-turbo Project nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <string.h>
#include <setjmp.h>
#include <errno.h>
#include "cdjpeg.h"
#include <jpeglib.h>
#include <jpegint.h>
#include "tjutil.h"
#include "bmp.h"
/* This duplicates the functionality of the VirtualGL bitmap library using
the components from cjpeg and djpeg */
/* Error handling (based on example in example.c) */
static char errStr[JMSG_LENGTH_MAX]="No error";
struct my_error_mgr
{
struct jpeg_error_mgr pub;
jmp_buf setjmp_buffer;
};
typedef struct my_error_mgr *my_error_ptr;
static void my_error_exit(j_common_ptr cinfo)
{
my_error_ptr myerr=(my_error_ptr)cinfo->err;
(*cinfo->err->output_message)(cinfo);
longjmp(myerr->setjmp_buffer, 1);
}
/* Based on output_message() in jerror.c */
static void my_output_message(j_common_ptr cinfo)
{
(*cinfo->err->format_message)(cinfo, errStr);
}
#define _throw(m) {snprintf(errStr, JMSG_LENGTH_MAX, "%s", m); \
retval=-1; goto bailout;}
#define _throwunix(m) {snprintf(errStr, JMSG_LENGTH_MAX, "%s\n%s", m, \
strerror(errno)); retval=-1; goto bailout;}
static void pixelconvert(unsigned char *srcbuf, int srcpf, int srcbottomup,
unsigned char *dstbuf, int dstpf, int dstbottomup, int w, int h)
{
unsigned char *srcrowptr=srcbuf, *srccolptr;
int srcps=tjPixelSize[srcpf];
int srcstride=srcbottomup? -w*srcps:w*srcps;
unsigned char *dstrowptr=dstbuf, *dstcolptr;
int dstps=tjPixelSize[dstpf];
int dststride=dstbottomup? -w*dstps:w*dstps;
int row, col;
if(srcbottomup) srcrowptr=&srcbuf[w*srcps*(h-1)];
if(dstbottomup) dstrowptr=&dstbuf[w*dstps*(h-1)];
/* NOTE: These quick & dirty CMYK<->RGB conversion routines are for testing
purposes only. Properly converting between CMYK and RGB requires a color
management system. */
if(dstpf==TJPF_CMYK)
{
for(row=0; row<h; row++, srcrowptr+=srcstride, dstrowptr+=dststride)
{
for(col=0, srccolptr=srcrowptr, dstcolptr=dstrowptr;
col<w; col++, srccolptr+=srcps)
{
double c=1.0-((double)(srccolptr[tjRedOffset[srcpf]])/255.);
double m=1.0-((double)(srccolptr[tjGreenOffset[srcpf]])/255.);
double y=1.0-((double)(srccolptr[tjBlueOffset[srcpf]])/255.);
double k=min(min(c,m),min(y,1.0));
if(k==1.0) c=m=y=0.0;
else
{
c=(c-k)/(1.0-k);
m=(m-k)/(1.0-k);
y=(y-k)/(1.0-k);
}
if(c>1.0) c=1.0; if(c<0.) c=0.;
if(m>1.0) m=1.0; if(m<0.) m=0.;
if(y>1.0) y=1.0; if(y<0.) y=0.;
if(k>1.0) k=1.0; if(k<0.) k=0.;
*dstcolptr++=(unsigned char)(255.0-c*255.0+0.5);
*dstcolptr++=(unsigned char)(255.0-m*255.0+0.5);
*dstcolptr++=(unsigned char)(255.0-y*255.0+0.5);
*dstcolptr++=(unsigned char)(255.0-k*255.0+0.5);
}
}
}
else if(srcpf==TJPF_CMYK)
{
for(row=0; row<h; row++, srcrowptr+=srcstride, dstrowptr+=dststride)
{
for(col=0, srccolptr=srcrowptr, dstcolptr=dstrowptr;
col<w; col++, dstcolptr+=dstps)
{
double c=(double)(*srccolptr++);
double m=(double)(*srccolptr++);
double y=(double)(*srccolptr++);
double k=(double)(*srccolptr++);
double r=c*k/255.;
double g=m*k/255.;
double b=y*k/255.;
if(r>255.0) r=255.0; if(r<0.) r=0.;
if(g>255.0) g=255.0; if(g<0.) g=0.;
if(b>255.0) b=255.0; if(b<0.) b=0.;
dstcolptr[tjRedOffset[dstpf]]=(unsigned char)(r+0.5);
dstcolptr[tjGreenOffset[dstpf]]=(unsigned char)(g+0.5);
dstcolptr[tjBlueOffset[dstpf]]=(unsigned char)(b+0.5);
}
}
}
else
{
for(row=0; row<h; row++, srcrowptr+=srcstride, dstrowptr+=dststride)
{
for(col=0, srccolptr=srcrowptr, dstcolptr=dstrowptr;
col<w; col++, srccolptr+=srcps, dstcolptr+=dstps)
{
dstcolptr[tjRedOffset[dstpf]]=srccolptr[tjRedOffset[srcpf]];
dstcolptr[tjGreenOffset[dstpf]]=srccolptr[tjGreenOffset[srcpf]];
dstcolptr[tjBlueOffset[dstpf]]=srccolptr[tjBlueOffset[srcpf]];
}
}
}
}
int loadbmp(char *filename, unsigned char **buf, int *w, int *h,
int dstpf, int bottomup)
{
int retval=0, dstps, srcpf, tempc;
struct jpeg_compress_struct cinfo;
struct my_error_mgr jerr;
cjpeg_source_ptr src;
FILE *file=NULL;
memset(&cinfo, 0, sizeof(struct jpeg_compress_struct));
if(!filename || !buf || !w || !h || dstpf<0 || dstpf>=TJ_NUMPF)
_throw("loadbmp(): Invalid argument");
if((file=fopen(filename, "rb"))==NULL)
_throwunix("loadbmp(): Cannot open input file");
cinfo.err=jpeg_std_error(&jerr.pub);
jerr.pub.error_exit=my_error_exit;
jerr.pub.output_message=my_output_message;
if(setjmp(jerr.setjmp_buffer))
{
/* If we get here, the JPEG code has signaled an error. */
retval=-1; goto bailout;
}
jpeg_create_compress(&cinfo);
if((tempc=getc(file))<0 || ungetc(tempc, file)==EOF)
_throwunix("loadbmp(): Could not read input file")
else if(tempc==EOF) _throw("loadbmp(): Input file contains no data");
if(tempc=='B')
{
if((src=jinit_read_bmp(&cinfo))==NULL)
_throw("loadbmp(): Could not initialize bitmap loader");
}
else if(tempc=='P')
{
if((src=jinit_read_ppm(&cinfo))==NULL)
_throw("loadbmp(): Could not initialize bitmap loader");
}
else _throw("loadbmp(): Unsupported file type");
src->input_file=file;
(*src->start_input)(&cinfo, src);
(*cinfo.mem->realize_virt_arrays)((j_common_ptr)&cinfo);
*w=cinfo.image_width; *h=cinfo.image_height;
if(cinfo.input_components==1 && cinfo.in_color_space==JCS_RGB)
srcpf=TJPF_GRAY;
else srcpf=TJPF_RGB;
dstps=tjPixelSize[dstpf];
if((*buf=(unsigned char *)malloc((*w)*(*h)*dstps))==NULL)
_throw("loadbmp(): Memory allocation failure");
while(cinfo.next_scanline<cinfo.image_height)
{
int i, nlines=(*src->get_pixel_rows)(&cinfo, src);
for(i=0; i<nlines; i++)
{
unsigned char *outbuf; int row;
row=cinfo.next_scanline+i;
if(bottomup) outbuf=&(*buf)[((*h)-row-1)*(*w)*dstps];
else outbuf=&(*buf)[row*(*w)*dstps];
pixelconvert(src->buffer[i], srcpf, 0, outbuf, dstpf, bottomup, *w,
nlines);
}
cinfo.next_scanline+=nlines;
}
(*src->finish_input)(&cinfo, src);
bailout:
jpeg_destroy_compress(&cinfo);
if(file) fclose(file);
if(retval<0 && buf && *buf) {free(*buf); *buf=NULL;}
return retval;
}
int savebmp(char *filename, unsigned char *buf, int w, int h, int srcpf,
int bottomup)
{
int retval=0, srcps, dstpf;
struct jpeg_decompress_struct dinfo;
struct my_error_mgr jerr;
djpeg_dest_ptr dst;
FILE *file=NULL;
char *ptr=NULL;
memset(&dinfo, 0, sizeof(struct jpeg_decompress_struct));
if(!filename || !buf || w<1 || h<1 || srcpf<0 || srcpf>=TJ_NUMPF)
_throw("savebmp(): Invalid argument");
if((file=fopen(filename, "wb"))==NULL)
_throwunix("savebmp(): Cannot open output file");
dinfo.err=jpeg_std_error(&jerr.pub);
jerr.pub.error_exit=my_error_exit;
jerr.pub.output_message=my_output_message;
if(setjmp(jerr.setjmp_buffer))
{
/* If we get here, the JPEG code has signaled an error. */
retval=-1; goto bailout;
}
jpeg_create_decompress(&dinfo);
if(srcpf==TJPF_GRAY)
{
dinfo.out_color_components=dinfo.output_components=1;
dinfo.out_color_space=JCS_GRAYSCALE;
}
else
{
dinfo.out_color_components=dinfo.output_components=3;
dinfo.out_color_space=JCS_RGB;
}
dinfo.image_width=w; dinfo.image_height=h;
dinfo.global_state=DSTATE_READY;
dinfo.scale_num=dinfo.scale_denom=1;
ptr=strrchr(filename, '.');
if(ptr && !strcasecmp(ptr, ".bmp"))
{
if((dst=jinit_write_bmp(&dinfo, 0))==NULL)
_throw("savebmp(): Could not initialize bitmap writer");
}
else
{
if((dst=jinit_write_ppm(&dinfo))==NULL)
_throw("savebmp(): Could not initialize PPM writer");
}
dst->output_file=file;
(*dst->start_output)(&dinfo, dst);
(*dinfo.mem->realize_virt_arrays)((j_common_ptr)&dinfo);
if(srcpf==TJPF_GRAY) dstpf=srcpf;
else dstpf=TJPF_RGB;
srcps=tjPixelSize[srcpf];
while(dinfo.output_scanline<dinfo.output_height)
{
int i, nlines=dst->buffer_height;
for(i=0; i<nlines; i++)
{
unsigned char *inbuf; int row;
row=dinfo.output_scanline+i;
if(bottomup) inbuf=&buf[(h-row-1)*w*srcps];
else inbuf=&buf[row*w*srcps];
pixelconvert(inbuf, srcpf, bottomup, dst->buffer[i], dstpf, 0, w,
nlines);
}
(*dst->put_pixel_rows)(&dinfo, dst, nlines);
dinfo.output_scanline+=nlines;
}
(*dst->finish_output)(&dinfo, dst);
bailout:
jpeg_destroy_decompress(&dinfo);
if(file) fclose(file);
return retval;
}
const char *bmpgeterr(void)
{
return errStr;
}

View File

@@ -1,9 +1,11 @@
/*
* cderror.h
*
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1994-1997, Thomas G. Lane.
* Modified 2009 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* Modified 2009-2017 by Guido Vollbeding.
* libjpeg-turbo Modifications:
* Copyright (C) 2021, 2024, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -26,7 +28,7 @@
#define JMAKE_ENUM_LIST
#else
/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */
#define JMESSAGE(code,string)
#define JMESSAGE(code, string)
#endif /* CDERROR_H */
#endif /* JMESSAGE */
@@ -34,31 +36,30 @@
typedef enum {
#define JMESSAGE(code,string) code ,
#define JMESSAGE(code, string) code,
#endif /* JMAKE_ENUM_LIST */
JMESSAGE(JMSG_FIRSTADDONCODE=1000, NULL) /* Must be first entry! */
JMESSAGE(JMSG_FIRSTADDONCODE = 1000, NULL) /* Must be first entry! */
#ifdef BMP_SUPPORTED
JMESSAGE(JERR_BMP_BADCMAP, "Unsupported BMP colormap format")
JMESSAGE(JERR_BMP_BADDEPTH, "Only 8- and 24-bit BMP files are supported")
JMESSAGE(JERR_BMP_BADDEPTH, "Only 8-, 24-, and 32-bit BMP files are supported")
JMESSAGE(JERR_BMP_BADHEADER, "Invalid BMP file: bad header length")
JMESSAGE(JERR_BMP_BADPLANES, "Invalid BMP file: biPlanes not equal to 1")
JMESSAGE(JERR_BMP_COLORSPACE, "BMP output must be grayscale or RGB")
JMESSAGE(JERR_BMP_COMPRESSED, "Sorry, compressed BMPs not yet supported")
JMESSAGE(JERR_BMP_EMPTY, "Empty BMP image")
JMESSAGE(JERR_BMP_NOT, "Not a BMP file - does not start with BM")
JMESSAGE(JTRC_BMP, "%ux%u 24-bit BMP image")
JMESSAGE(JERR_BMP_OUTOFRANGE, "Numeric value out of range in BMP file")
JMESSAGE(JTRC_BMP, "%ux%u %d-bit BMP image")
JMESSAGE(JTRC_BMP_MAPPED, "%ux%u 8-bit colormapped BMP image")
JMESSAGE(JTRC_BMP_OS2, "%ux%u 24-bit OS2 BMP image")
JMESSAGE(JTRC_BMP_OS2, "%ux%u %d-bit OS2 BMP image")
JMESSAGE(JTRC_BMP_OS2_MAPPED, "%ux%u 8-bit colormapped OS2 BMP image")
#endif /* BMP_SUPPORTED */
#ifdef GIF_SUPPORTED
JMESSAGE(JERR_GIF_BUG, "GIF output got confused")
JMESSAGE(JERR_GIF_CODESIZE, "Bogus GIF codesize %d")
JMESSAGE(JERR_GIF_COLORSPACE, "GIF output must be grayscale or RGB")
JMESSAGE(JERR_GIF_EMPTY, "Empty GIF image")
JMESSAGE(JERR_GIF_IMAGENOTFOUND, "Too few images in GIF file")
JMESSAGE(JERR_GIF_NOT, "Not a GIF file")
JMESSAGE(JTRC_GIF, "%ux%ux%d GIF image")
@@ -70,62 +71,40 @@ JMESSAGE(JWRN_GIF_BADDATA, "Corrupt data in GIF file")
JMESSAGE(JWRN_GIF_CHAR, "Bogus char 0x%02x in GIF file, ignoring")
JMESSAGE(JWRN_GIF_ENDCODE, "Premature end of GIF image")
JMESSAGE(JWRN_GIF_NOMOREDATA, "Ran out of GIF bits")
#endif /* GIF_SUPPORTED */
#ifdef PPM_SUPPORTED
JMESSAGE(JERR_PPM_COLORSPACE, "PPM output must be grayscale or RGB")
JMESSAGE(JERR_PPM_NONNUMERIC, "Nonnumeric data in PPM file")
JMESSAGE(JERR_PPM_TOOLARGE, "Integer value too large in PPM file")
JMESSAGE(JERR_PPM_NOT, "Not a PPM/PGM file")
JMESSAGE(JTRC_PGM, "%ux%u PGM image")
JMESSAGE(JTRC_PGM_TEXT, "%ux%u text PGM image")
JMESSAGE(JTRC_PPM, "%ux%u PPM image")
JMESSAGE(JTRC_PPM_TEXT, "%ux%u text PPM image")
#endif /* PPM_SUPPORTED */
JMESSAGE(JERR_PPM_OUTOFRANGE, "Numeric value out of range in PPM file")
JMESSAGE(JTRC_PGM, "%ux%u PGM image (maximum color value = %u)")
JMESSAGE(JTRC_PGM_TEXT, "%ux%u text PGM image (maximum color value = %u)")
JMESSAGE(JTRC_PPM, "%ux%u PPM image (maximum color value = %u)")
JMESSAGE(JTRC_PPM_TEXT, "%ux%u text PPM image (maximum color value = %u)")
#ifdef RLE_SUPPORTED
JMESSAGE(JERR_RLE_BADERROR, "Bogus error code from RLE library")
JMESSAGE(JERR_RLE_COLORSPACE, "RLE output must be grayscale or RGB")
JMESSAGE(JERR_RLE_DIMENSIONS, "Image dimensions (%ux%u) too large for RLE")
JMESSAGE(JERR_RLE_EMPTY, "Empty RLE file")
JMESSAGE(JERR_RLE_EOF, "Premature EOF in RLE header")
JMESSAGE(JERR_RLE_MEM, "Insufficient memory for RLE header")
JMESSAGE(JERR_RLE_NOT, "Not an RLE file")
JMESSAGE(JERR_RLE_TOOMANYCHANNELS, "Cannot handle %d output channels for RLE")
JMESSAGE(JERR_RLE_UNSUPPORTED, "Cannot handle this RLE setup")
JMESSAGE(JTRC_RLE, "%ux%u full-color RLE file")
JMESSAGE(JTRC_RLE_FULLMAP, "%ux%u full-color RLE file with map of length %d")
JMESSAGE(JTRC_RLE_GRAY, "%ux%u grayscale RLE file")
JMESSAGE(JTRC_RLE_MAPGRAY, "%ux%u grayscale RLE file with map of length %d")
JMESSAGE(JTRC_RLE_MAPPED, "%ux%u colormapped RLE file with map of length %d")
#endif /* RLE_SUPPORTED */
#ifdef TARGA_SUPPORTED
JMESSAGE(JERR_TGA_BADCMAP, "Unsupported Targa colormap format")
JMESSAGE(JERR_TGA_BADPARMS, "Invalid or unsupported Targa file")
JMESSAGE(JERR_TGA_COLORSPACE, "Targa output must be grayscale or RGB")
JMESSAGE(JTRC_TGA, "%ux%u RGB Targa image")
JMESSAGE(JTRC_TGA_GRAY, "%ux%u grayscale Targa image")
JMESSAGE(JTRC_TGA_MAPPED, "%ux%u colormapped Targa image")
#else
JMESSAGE(JERR_TGA_NOTCOMP, "Targa support was not compiled")
#endif /* TARGA_SUPPORTED */
JMESSAGE(JERR_BAD_CMAP_FILE,
"Color map file is invalid or of unsupported format")
JMESSAGE(JERR_TOO_MANY_COLORS,
"Output file format cannot handle %d colormap entries")
JMESSAGE(JERR_UNGETC_FAILED, "ungetc failed")
#ifdef TARGA_SUPPORTED
#ifdef PNG_SUPPORTED
JMESSAGE(JERR_UNKNOWN_FORMAT,
"Unrecognized input file format --- perhaps you need -targa")
"MozJPEG can't read the image (JPEG, PNG and old BMP and Targa are supported)")
#else
JMESSAGE(JERR_UNKNOWN_FORMAT, "Unrecognized input file format")
JMESSAGE(JERR_UNKNOWN_FORMAT, "MozJPEG can't read the image (PNG support is disabled in this build)")
#endif
JMESSAGE(JERR_UNSUPPORTED_FORMAT, "Unsupported output file format")
#ifdef PNG_SUPPORTED
JMESSAGE(JERR_PNG_ERROR, "Unable to read PNG file: %s")
JMESSAGE(JERR_PNG_PROFILETOOLARGE, "Embedded profile was too large for this tool - dropped.")
#endif
#ifdef JMAKE_ENUM_LIST

View File

@@ -3,8 +3,8 @@
*
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1991-1997, Thomas G. Lane.
* It was modified by The libjpeg-turbo Project to include only code relevant
* to libjpeg-turbo.
* libjpeg-turbo Modifications:
* Copyright (C) 2019, 2022, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -25,37 +25,51 @@
* Optional progress monitor: display a percent-done figure on stderr.
*/
#ifdef PROGRESS_REPORT
METHODDEF(void)
progress_monitor (j_common_ptr cinfo)
progress_monitor(j_common_ptr cinfo)
{
cd_progress_ptr prog = (cd_progress_ptr) cinfo->progress;
int total_passes = prog->pub.total_passes + prog->total_extra_passes;
int percent_done = (int) (prog->pub.pass_counter*100L/prog->pub.pass_limit);
cd_progress_ptr prog = (cd_progress_ptr)cinfo->progress;
if (percent_done != prog->percent_done) {
prog->percent_done = percent_done;
if (total_passes > 1) {
fprintf(stderr, "\rPass %d/%d: %3d%% ",
prog->pub.completed_passes + prog->completed_extra_passes + 1,
total_passes, percent_done);
} else {
fprintf(stderr, "\r %3d%% ", percent_done);
if (prog->max_scans != 0 && cinfo->is_decompressor) {
int scan_no = ((j_decompress_ptr)cinfo)->input_scan_number;
if (scan_no > (int)prog->max_scans) {
fprintf(stderr, "Scan number %d exceeds maximum scans (%u)\n", scan_no,
prog->max_scans);
exit(EXIT_FAILURE);
}
}
if (prog->report) {
int total_passes = prog->pub.total_passes + prog->total_extra_passes;
int percent_done =
(int)(prog->pub.pass_counter * 100L / prog->pub.pass_limit);
if (percent_done != prog->percent_done) {
prog->percent_done = percent_done;
if (total_passes > 1) {
fprintf(stderr, "\rPass %d/%d: %3d%% ",
prog->pub.completed_passes + prog->completed_extra_passes + 1,
total_passes, percent_done);
} else {
fprintf(stderr, "\r %3d%% ", percent_done);
}
fflush(stderr);
}
fflush(stderr);
}
}
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 */
if (cinfo->err->trace_level == 0) {
progress->pub.progress_monitor = progress_monitor;
progress->completed_extra_passes = 0;
progress->total_extra_passes = 0;
progress->max_scans = 0;
progress->report = FALSE;
progress->percent_done = -1;
cinfo->progress = &progress->pub;
}
@@ -63,7 +77,7 @@ start_progress_monitor (j_common_ptr cinfo, cd_progress_ptr progress)
GLOBAL(void)
end_progress_monitor (j_common_ptr cinfo)
end_progress_monitor(j_common_ptr cinfo)
{
/* Clear away progress display */
if (cinfo->err->trace_level == 0) {
@@ -72,8 +86,6 @@ end_progress_monitor (j_common_ptr cinfo)
}
}
#endif
/*
* Case-insensitive matching of possibly-abbreviated keyword switches.
@@ -82,7 +94,7 @@ end_progress_monitor (j_common_ptr cinfo)
*/
GLOBAL(boolean)
keymatch (char *arg, const char *keyword, int minchars)
keymatch(char *arg, const char *keyword, int minchars)
{
register int ca, ck;
register int nmatched = 0;
@@ -109,9 +121,9 @@ keymatch (char *arg, const char *keyword, int minchars)
*/
GLOBAL(FILE *)
read_stdin (void)
read_stdin(void)
{
FILE * input_file = stdin;
FILE *input_file = stdin;
#ifdef USE_SETMODE /* need to hack file mode? */
setmode(fileno(stdin), O_BINARY);
@@ -127,9 +139,9 @@ read_stdin (void)
GLOBAL(FILE *)
write_stdout (void)
write_stdout(void)
{
FILE * output_file = stdout;
FILE *output_file = stdout;
#ifdef USE_SETMODE /* need to hack file mode? */
setmode(fileno(stdout), O_BINARY);

View File

@@ -3,11 +3,12 @@
*
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1994-1997, Thomas G. Lane.
* It was modified by The libjpeg-turbo Project to include only code relevant
* to libjpeg-turbo.
* mozjpeg Modifications:
* Modified 2019 by Guido Vollbeding.
* libjpeg-turbo Modifications:
* Copyright (C) 2017, 2019, 2021-2022, D. R. Commander.
* Copyright (C) 2014, Mozilla Corporation.
* For conditions of distribution and use, see the accompanying README.ijg file.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
* This file contains common declarations for the sample applications
* cjpeg and djpeg. It is NOT used by the core JPEG library.
@@ -36,8 +37,12 @@ struct cjpeg_source_struct {
FILE *input_file;
JSAMPARRAY buffer;
J12SAMPARRAY buffer12;
#ifdef C_LOSSLESS_SUPPORTED
J16SAMPARRAY buffer16;
#endif
JDIMENSION buffer_height;
JDIMENSION max_pixels;
#if JPEG_RAW_READER
// For reading JPEG
JSAMPARRAY plane_pointer[4];
@@ -63,6 +68,14 @@ struct djpeg_dest_struct {
JDIMENSION rows_supplied);
/* Finish up at the end of the image. */
void (*finish_output) (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo);
/* Re-calculate buffer dimensions based on output dimensions (for use with
partial image decompression.) If this is NULL, then the output format
does not support partial image decompression (BMP, in particular, cannot
support partial decompression because it uses an inversion buffer to write
the image in bottom-up order.) */
void (*calc_buffer_dimensions) (j_decompress_ptr cinfo,
djpeg_dest_ptr dinfo);
/* Target file spec; filled in by djpeg.c after object is created. */
FILE *output_file;
@@ -72,6 +85,10 @@ struct djpeg_dest_struct {
* height is buffer_height.
*/
JSAMPARRAY buffer;
J12SAMPARRAY buffer12;
#ifdef D_LOSSLESS_SUPPORTED
J16SAMPARRAY buffer16;
#endif
JDIMENSION buffer_height;
};
@@ -88,6 +105,9 @@ struct cdjpeg_progress_mgr {
struct jpeg_progress_mgr pub; /* fields known to JPEG library */
int completed_extra_passes; /* extra passes completed */
int total_extra_passes; /* total extra */
JDIMENSION max_scans; /* abort if the number of scans exceeds this
value and the value is non-zero */
boolean report; /* whether or not to report progress */
/* last printed percentage stored here to avoid multiple printouts */
int percent_done;
};
@@ -97,43 +117,56 @@ typedef struct cdjpeg_progress_mgr *cd_progress_ptr;
/* Module selection routines for I/O modules. */
EXTERN(cjpeg_source_ptr) jinit_read_bmp (j_compress_ptr cinfo);
EXTERN(djpeg_dest_ptr) jinit_write_bmp (j_decompress_ptr cinfo,
boolean is_os2);
EXTERN(cjpeg_source_ptr) jinit_read_gif (j_compress_ptr cinfo);
EXTERN(djpeg_dest_ptr) jinit_write_gif (j_decompress_ptr cinfo);
EXTERN(cjpeg_source_ptr) jinit_read_jpeg (j_compress_ptr cinfo);
EXTERN(cjpeg_source_ptr) jinit_read_ppm (j_compress_ptr cinfo);
EXTERN(cjpeg_source_ptr) jinit_read_png (j_compress_ptr cinfo);
EXTERN(djpeg_dest_ptr) jinit_write_ppm (j_decompress_ptr cinfo);
EXTERN(cjpeg_source_ptr) jinit_read_rle (j_compress_ptr cinfo);
EXTERN(djpeg_dest_ptr) jinit_write_rle (j_decompress_ptr cinfo);
EXTERN(cjpeg_source_ptr) jinit_read_targa (j_compress_ptr cinfo);
EXTERN(djpeg_dest_ptr) jinit_write_targa (j_decompress_ptr cinfo);
EXTERN(cjpeg_source_ptr) jinit_read_bmp(j_compress_ptr cinfo,
boolean use_inversion_array);
EXTERN(djpeg_dest_ptr) jinit_write_bmp(j_decompress_ptr cinfo, boolean is_os2,
boolean use_inversion_array);
EXTERN(cjpeg_source_ptr) jinit_read_gif(j_compress_ptr cinfo);
EXTERN(cjpeg_source_ptr) j12init_read_gif(j_compress_ptr cinfo);
#ifdef C_LOSSLESS_SUPPORTED
EXTERN(cjpeg_source_ptr) j16init_read_gif(j_compress_ptr cinfo);
#endif
EXTERN(djpeg_dest_ptr) jinit_write_gif(j_decompress_ptr cinfo, boolean is_lzw);
EXTERN(djpeg_dest_ptr) j12init_write_gif(j_decompress_ptr cinfo,
boolean is_lzw);
EXTERN(cjpeg_source_ptr) jinit_read_ppm(j_compress_ptr cinfo);
EXTERN(cjpeg_source_ptr) j12init_read_ppm(j_compress_ptr cinfo);
#ifdef C_LOSSLESS_SUPPORTED
EXTERN(cjpeg_source_ptr) j16init_read_ppm(j_compress_ptr cinfo);
#endif
EXTERN(djpeg_dest_ptr) jinit_write_ppm(j_decompress_ptr cinfo);
EXTERN(djpeg_dest_ptr) j12init_write_ppm(j_decompress_ptr cinfo);
#ifdef D_LOSSLESS_SUPPORTED
EXTERN(djpeg_dest_ptr) j16init_write_ppm(j_decompress_ptr cinfo);
#endif
EXTERN(cjpeg_source_ptr) jinit_read_targa(j_compress_ptr cinfo);
EXTERN(djpeg_dest_ptr) jinit_write_targa(j_decompress_ptr cinfo);
/* cjpeg support routines (in rdswitch.c) */
EXTERN(boolean) read_quant_tables (j_compress_ptr cinfo, char *filename,
boolean force_baseline);
EXTERN(boolean) read_scan_script (j_compress_ptr cinfo, char *filename);
EXTERN(boolean) set_quality_ratings (j_compress_ptr cinfo, char *arg,
boolean force_baseline);
EXTERN(boolean) set_quant_slots (j_compress_ptr cinfo, char *arg);
EXTERN(boolean) set_sample_factors (j_compress_ptr cinfo, char *arg);
EXTERN(boolean) read_quant_tables(j_compress_ptr cinfo, char *filename,
boolean force_baseline);
EXTERN(boolean) read_scan_script(j_compress_ptr cinfo, char *filename);
EXTERN(boolean) set_quality_ratings(j_compress_ptr cinfo, char *arg,
boolean force_baseline);
EXTERN(boolean) set_quant_slots(j_compress_ptr cinfo, char *arg);
EXTERN(boolean) set_sample_factors(j_compress_ptr cinfo, char *arg);
/* djpeg support routines (in rdcolmap.c) */
EXTERN(void) read_color_map (j_decompress_ptr cinfo, FILE *infile);
EXTERN(void) read_color_map(j_decompress_ptr cinfo, FILE *infile);
EXTERN(void) read_color_map_12(j_decompress_ptr cinfo, FILE *infile);
/* common support routines (in cdjpeg.c) */
EXTERN(void) enable_signal_catcher (j_common_ptr cinfo);
EXTERN(void) start_progress_monitor (j_common_ptr cinfo,
cd_progress_ptr progress);
EXTERN(void) end_progress_monitor (j_common_ptr cinfo);
EXTERN(boolean) keymatch (char *arg, const char *keyword, int minchars);
EXTERN(FILE *) read_stdin (void);
EXTERN(FILE *) write_stdout (void);
EXTERN(void) start_progress_monitor(j_common_ptr cinfo,
cd_progress_ptr progress);
EXTERN(void) end_progress_monitor(j_common_ptr cinfo);
EXTERN(boolean) keymatch(char *arg, const char *keyword, int minchars);
EXTERN(FILE *) read_stdin(void);
EXTERN(FILE *) write_stdout(void);
/* miscellaneous useful macros */

View File

@@ -6,6 +6,25 @@ reference. Please see ChangeLog.md for information specific to libjpeg-turbo.
CHANGE LOG for Independent JPEG Group's JPEG software
Version 9d 12-Jan-2020
-----------------------
Restore GIF read and write support from libjpeg version 6a.
Thank to Wolfgang Werner (W.W.) Heinz for suggestion.
Add jpegtran -drop option; add options to the crop extension and wipe
to fill the extra area with content from the source image region,
instead of gray out.
Version 9c 14-Jan-2018
-----------------------
jpegtran: add an option to the -wipe switch to fill the region
with the average of adjacent blocks, instead of gray out.
Thank to Caitlyn Feddock and Maddie Ziegler for inspiration.
Version 9b 17-Jan-2016
-----------------------
@@ -13,6 +32,13 @@ Document 'f' specifier for jpegtran -crop specification.
Thank to Michele Martone for suggestion.
Version 9a 19-Jan-2014
-----------------------
Add jpegtran -wipe option and extension for -crop.
Thank to Andrew Senior, David Clunie, and Josef Schmid for suggestion.
Version 9 13-Jan-2013
----------------------
@@ -138,11 +164,6 @@ 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

206
cjpeg.1
View File

@@ -1,4 +1,4 @@
.TH CJPEG 1 "17 February 2016"
.TH CJPEG 1 "30 August 2024"
.SH NAME
cjpeg \- compress an image file to a JPEG file
.SH SYNOPSIS
@@ -16,8 +16,8 @@ cjpeg \- compress an image file to a JPEG file
compresses the named image file, or the standard input if no file is
named, and produces a JPEG/JFIF file on the standard output.
The currently supported input file formats are: PPM (PBMPLUS color
format), PGM (PBMPLUS grayscale format), BMP, Targa, and RLE (Utah Raster
Toolkit format). (RLE is supported only if the URT library is available.)
format), PGM (PBMPLUS grayscale format), BMP, GIF [legacy feature], and Targa
[legacy feature].
.SH OPTIONS
All switch names may be abbreviated; for example,
.B \-grayscale
@@ -30,7 +30,7 @@ Upper and lower case are equivalent (thus
.B \-BMP
is the same as
.BR \-bmp ).
British spellings are also accepted (e.g.,
British spellings are also accepted (e.g.
.BR \-greyscale ),
though for brevity these are not mentioned below.
.PP
@@ -41,17 +41,12 @@ Scale quantization tables to adjust image quality. Quality is 0 (worst) to
100 (best); default is 75. (See below for more info.)
.TP
.B \-grayscale
Create monochrome JPEG file from color input. Be sure to use this switch when
compressing a grayscale BMP file, because
.B cjpeg
isn't bright enough to notice whether a BMP file uses only shades of gray.
By saying
.BR \-grayscale ,
Create monochrome JPEG file from color input. By specifying
.BR \-grayscale,
you'll get a smaller JPEG file that takes less time to process.
.TP
.B \-rgb
Create RGB JPEG file.
Using this switch suppresses the conversion from RGB
Create RGB JPEG file. Using this switch suppresses the conversion from RGB
colorspace input to the default YCbCr JPEG colorspace.
.TP
.B \-optimize
@@ -65,18 +60,22 @@ decompression are unaffected by
.BR \-optimize .
.TP
.B \-progressive
Create progressive JPEG file (see below).
Create progressive JPEG file (see below). Implies
.B \-optimize
unless
.B \-arithmetic
is also specified.
.TP
.B \-targa
Input file is Targa format. Targa files that contain an "identification"
field will not be automatically recognized by
.BR cjpeg ;
for such files you must specify
Input file is Targa format [legacy feature]. Targa files that contain an
"identification" field will not be automatically recognized by
.BR cjpeg .
For such files, you must specify
.B \-targa
to make
.B cjpeg
treat the input as Targa format.
For most Targa files, you won't need this switch.
treat the input as Targa format. For most Targa files, you won't need this
switch.
.PP
The
.B \-quality
@@ -154,42 +153,135 @@ about the same --- often a little smaller.
.PP
Switches for advanced users:
.TP
.BI \-precision " N"
Create JPEG file with N-bit data precision. N is 8, 12, or 16; default is 8.
If N is 16, then
.B -lossless
must also be specified. Note that only the PBMPLUS input file format supports
data precisions other than 8. (For historical reasons,
.B cjpeg
allows GIF input files to be converted into 12-bit-per-sample JPEG files, but
this is not a useful conversion.) Note also that PBMPLUS input files are
silently scaled to the target data precision, even if it is lower than the
precision of the input file. Passing an argument of
.B \-verbose
to
.B cjpeg
will cause it to print information about the precision of the input file.
.B Caution:
12-bit and 16-bit data precision is not yet widely implemented, so many
decoders will be unable to handle a 12-bit-per-sample or 16-bit-per-sample JPEG
file at all.
.IP
.B \-precision\ 12
implies
.B \-optimize
unless
.B \-arithmetic
is also specified.
.TP
.BI \-lossless " psv[,Pt]"
Create a lossless JPEG file using the specified predictor selection value
(1 through 7) and optional point transform (0 through
.nh
.I precision
.hy
- 1, where
.nh
.I precision
.hy
is the JPEG data precision in bits). A point transform value of 0 (the
default) is necessary in order to create a fully lossless JPEG file. (A
non-zero point transform value right-shifts the input samples by the specified
number of bits, which is effectively a form of lossy color quantization.)
.B Caution:
lossless JPEG is not yet widely implemented, so many decoders will be unable to
handle a lossless JPEG file at all. In most cases, compressing and
decompressing a lossless JPEG file is considerably slower than compressing and
decompressing a lossy JPEG file, and lossless JPEG files are much larger than
lossy JPEG files. Also note that the following features will be unavailable
when compressing or decompressing a lossless JPEG file:
.IP
- Quality/quantization table selection
.IP
- Color space conversion (the JPEG image will use the same color space as the
input image)
.IP
- Color quantization
.IP
- DCT/IDCT algorithm selection
.IP
- Smoothing
.IP
- Downsampling/upsampling
.IP
- IDCT scaling
.IP
- Partial image decompression
.IP
- Transformations using
.B jpegtran
.IP
Any switches used to enable or configure those features will be ignored.
.TP
.B \-arithmetic
Use arithmetic coding.
.B Caution:
arithmetic coded JPEG is not yet widely implemented, so many decoders will be
unable to view an arithmetic coded JPEG file at all.
arithmetic-coded JPEG is not yet widely implemented, so many decoders will be
unable to handle an arithmetic-coded JPEG file at all.
.TP
.B \-dct int
Use integer DCT method (default).
Use accurate integer DCT method (default).
.TP
.B \-dct fast
Use fast integer DCT (less accurate).
In libjpeg-turbo, the fast method is generally about 5-15% faster than the int
method when using the x86/x86-64 SIMD extensions (results may vary with other
SIMD implementations, or when using libjpeg-turbo without SIMD extensions.)
Use less accurate integer DCT method [legacy feature].
When the Independent JPEG Group's software was first released in 1991, the
compression time for a 1-megapixel JPEG image on a mainstream PC was measured
in minutes. Thus, the \fBfast\fR integer DCT algorithm provided noticeable
performance benefits. On modern CPUs running libjpeg-turbo, however, the
compression time for a 1-megapixel JPEG image is measured in milliseconds, and
thus the performance benefits of the \fBfast\fR algorithm are much less
noticeable. On modern x86/x86-64 CPUs that support AVX2 instructions, the
\fBfast\fR and \fBint\fR methods have similar performance. On other types of
CPUs, the \fBfast\fR method is generally about 5-15% faster than the \fBint\fR
method.
For quality levels of 90 and below, there should be little or no perceptible
difference between the two algorithms. For quality levels above 90, however,
the difference between the fast and the int methods becomes more pronounced.
With quality=97, for instance, the fast method incurs generally about a 1-3 dB
loss (in PSNR) relative to the int method, but this can be larger for some
images. Do not use the fast method with quality levels above 97. The
algorithm often degenerates at quality=98 and above and can actually produce a
more lossy image than if lower quality levels had been used. Also, in
libjpeg-turbo, the fast method is not fully accelerated for quality levels
above 97, so it will be slower than the int method.
quality difference between the two algorithms. For quality levels above 90,
however, the difference between the \fBfast\fR and \fBint\fR methods becomes
more pronounced. With quality=97, for instance, the \fBfast\fR method incurs
generally about a 1-3 dB loss in PSNR relative to the \fBint\fR method, but
this can be larger for some images. Do not use the \fBfast\fR method with
quality levels above 97. The algorithm often degenerates at quality=98 and
above and can actually produce a more lossy image than if lower quality levels
had been used. Also, in libjpeg-turbo, the \fBfast\fR method is not fully
accelerated for quality levels above 97, so it will be slower than the
\fBint\fR method.
.TP
.B \-dct float
Use floating-point DCT method.
The float method is mainly a legacy feature. It does not produce significantly
more accurate results than the int method, and it is much slower. The float
method may also give different results on different machines due to varying
roundoff behavior, whereas the integer methods should give the same results on
all machines.
Use floating-point DCT method [legacy feature].
The \fBfloat\fR method does not produce significantly more accurate results
than the \fBint\fR method, and it is much slower. The \fBfloat\fR method may
also give different results on different machines due to varying roundoff
behavior, whereas the integer methods should give the same results on all
machines.
.TP
.BI \-icc " file"
Embed ICC color management profile contained in the specified file.
.TP
.BI \-restart " N"
Emit a JPEG restart marker every N MCU rows, or every N MCU blocks if "B" is
attached to the number.
Emit a JPEG restart marker every N MCU rows, or every N MCUs if "B" is attached
to the number.
.IP
In typical JPEG images, an MCU (Minimum Coded Unit) is the minimum set of
interleaved "data units" (8x8 DCT blocks if the image is lossy or samples if
the image is lossless) necessary to represent at least one data unit per
component. (For example, an MCU in an interleaved lossy JPEG image that uses
4:2:2 subsampling consists of two luminance blocks followed by one block for
each chrominance component.) In single-component or non-interleaved JPEG
images, an MCU is the same as a data unit. An MCU row is a row of MCUs
spanning the entire width of the image.
.IP
.B \-restart 0
(the default) means no restart markers.
.TP
@@ -202,7 +294,7 @@ Set limit for amount of memory to use in processing large images. Value is
in thousands of bytes, or millions of bytes if "M" is attached to the
number. For example,
.B \-max 4m
selects 4000000 bytes. If more space is needed, temporary files will be used.
selects 4000000 bytes. If more space is needed, an error will occur.
.TP
.BI \-outfile " name"
Send output image to the named file, not to standard output.
@@ -212,6 +304,14 @@ Compress to memory instead of a file. This feature was implemented mainly as a
way of testing the in-memory destination manager (jpeg_mem_dest()), but it is
also useful for benchmarking, since it reduces the I/O overhead.
.TP
.BI \-report
Report compression progress.
.TP
.BI \-strict
Treat all warnings as fatal. Enabling this option will cause the compressor to
abort if an LZW-compressed GIF input image contains incomplete or corrupt image
data.
.TP
.B \-verbose
Enable debug printout. More
.BR \-v 's
@@ -281,10 +381,10 @@ This example compresses the PPM file foo.ppm with a quality factor of
.I foo.jpg
.SH HINTS
Color GIF files are not the ideal input for JPEG; JPEG is really intended for
compressing full-color (24-bit) images. In particular, don't try to convert
cartoons, line drawings, and other images that have only a few distinct
colors. GIF works great on these, JPEG does not. If you want to convert a
GIF to JPEG, you should experiment with
compressing full-color (24-bit through 48-bit) images. In particular, don't
try to convert cartoons, line drawings, and other images that have only a few
distinct colors. GIF works great on these; JPEG does not. If you want to
convert a GIF to JPEG, you should experiment with
.BR cjpeg 's
.B \-quality
and
@@ -338,14 +438,4 @@ This file was modified by The libjpeg-turbo Project to include only information
relevant to libjpeg-turbo, to wordsmith certain sections, and to describe
features not present in libjpeg.
.SH ISSUES
Support for GIF input files was removed in cjpeg v6b due to concerns over
the Unisys LZW patent. Although this patent expired in 2006, cjpeg still
lacks GIF support, for these historical reasons. (Conversion of GIF files to
JPEG is usually a bad idea anyway, since GIF is a 256-color format.)
.PP
Not all variants of BMP and Targa file formats are supported.
.PP
The
.B \-targa
switch is not a bug, it's a feature. (It would be a bug if the Targa format
designers had not been clueless.)

374
cjpeg.c
View File

@@ -4,11 +4,13 @@
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1991-1998, Thomas G. Lane.
* Modified 2003-2011 by Guido Vollbeding.
* Lossless JPEG Modifications:
* Copyright (C) 1999, Ken Murchison.
* libjpeg-turbo Modifications:
* Copyright (C) 2010, 2013-2014, D. R. Commander.
* mozjpeg Modifications:
* Copyright (C) 2010, 2013-2014, 2017, 2019-2022, 2024, D. R. Commander.
* Copyright (C) 2014, Mozilla Corporation.
* For conditions of distribution and use, see the accompanying README file.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
* This file contains a command-line user interface for the JPEG compressor.
* It should work on any system with Unix- or MS-DOS-style command lines.
@@ -28,24 +30,21 @@
* works regardless of which command line style is used.
*/
#ifdef _MSC_VER
#define _CRT_SECURE_NO_DEPRECATE
#endif
#ifdef CJPEG_FUZZER
#define JPEG_INTERNALS
#endif
#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
#include "jversion.h" /* for version message */
#include "jconfigint.h"
#ifdef USE_CCOMMAND /* command-line reader for Macintosh */
#ifdef __MWERKS__
#include <SIOUX.h> /* Metrowerks needs this */
#include <console.h> /* ... and this */
#endif
#ifdef THINK_C
#include <console.h> /* Think declares it here */
#endif
#endif
/* Create the add-on message string table. */
#define JMESSAGE(code,string) string ,
#define JMESSAGE(code, string) string,
static const char * const cdjpeg_message_table[] = {
#include "cderror.h"
@@ -65,9 +64,9 @@ static const char * const cdjpeg_message_table[] = {
* 2) assume we can push back more than one character (works in
* some C implementations, but unportable);
* 3) provide our own buffering (breaks input readers that want to use
* stdio directly, such as the RLE library);
* stdio directly);
* or 4) don't put back the data, and modify the input_init methods to assume
* they start reading after the start of file (also breaks RLE library).
* they start reading after the start of file.
* #1 is attractive for MS-DOS but is untenable on Unix.
*
* The most portable solution for file types that can't be identified by their
@@ -81,9 +80,10 @@ static const char * const cdjpeg_message_table[] = {
static boolean is_targa; /* records user -targa switch */
static boolean is_jpeg;
static boolean copy_markers;
LOCAL(cjpeg_source_ptr)
select_file_type (j_compress_ptr cinfo, FILE *infile)
select_file_type(j_compress_ptr cinfo, FILE *infile)
{
int c;
@@ -103,30 +103,48 @@ select_file_type (j_compress_ptr cinfo, FILE *infile)
switch (c) {
#ifdef BMP_SUPPORTED
case 'B':
return jinit_read_bmp(cinfo);
return jinit_read_bmp(cinfo, TRUE);
#endif
#ifdef GIF_SUPPORTED
case 'G':
return jinit_read_gif(cinfo);
if (cinfo->data_precision == 16) {
#ifdef C_LOSSLESS_SUPPORTED
return j16init_read_gif(cinfo);
#else
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
break;
#endif
} else if (cinfo->data_precision == 12)
return j12init_read_gif(cinfo);
else
return jinit_read_gif(cinfo);
#endif
#ifdef PPM_SUPPORTED
case 'P':
return jinit_read_ppm(cinfo);
if (cinfo->data_precision == 16) {
#ifdef C_LOSSLESS_SUPPORTED
return j16init_read_ppm(cinfo);
#else
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
break;
#endif
} else if (cinfo->data_precision == 12)
return j12init_read_ppm(cinfo);
else
return jinit_read_ppm(cinfo);
#endif
#ifdef PNG_SUPPORTED
case 0x89:
copy_markers = TRUE;
return jinit_read_png(cinfo);
#endif
#ifdef RLE_SUPPORTED
case 'R':
return jinit_read_rle(cinfo);
#endif
#ifdef TARGA_SUPPORTED
case 0x00:
return jinit_read_targa(cinfo);
#endif
case 0xff:
is_jpeg = TRUE;
copy_markers = TRUE;
return jinit_read_jpeg(cinfo);
default:
ERREXIT(cinfo, JERR_UNKNOWN_FORMAT);
@@ -147,12 +165,54 @@ select_file_type (j_compress_ptr cinfo, FILE *infile)
static const char *progname; /* program name for error messages */
static char *icc_filename; /* for -icc switch */
static char *outfilename; /* for -outfile switch */
boolean memdst; /* for -memdst switch */
static boolean memdst; /* for -memdst switch */
static boolean report; /* for -report switch */
static boolean strict; /* for -strict switch */
#ifdef CJPEG_FUZZER
#include <setjmp.h>
struct my_error_mgr {
struct jpeg_error_mgr pub;
jmp_buf setjmp_buffer;
};
void my_error_exit(j_common_ptr cinfo)
{
struct my_error_mgr *myerr = (struct my_error_mgr *)cinfo->err;
longjmp(myerr->setjmp_buffer, 1);
}
static void my_emit_message_fuzzer(j_common_ptr cinfo, int msg_level)
{
if (msg_level < 0)
cinfo->err->num_warnings++;
}
#define HANDLE_ERROR() { \
if (cinfo.global_state > CSTATE_START) { \
if (memdst && outbuffer) \
(*cinfo.dest->term_destination) (&cinfo); \
jpeg_abort_compress(&cinfo); \
} \
jpeg_destroy_compress(&cinfo); \
if (input_file != stdin && input_file != NULL) \
fclose(input_file); \
if (memdst) \
free(outbuffer); \
return EXIT_FAILURE; \
}
#endif
LOCAL(void)
usage (void)
usage(void)
/* complain about bad command line */
{
fprintf(stderr, "usage: %s [switches] ", progname);
@@ -168,10 +228,10 @@ usage (void)
fprintf(stderr, " -grayscale Create monochrome JPEG file\n");
fprintf(stderr, " -rgb Create RGB JPEG file\n");
#ifdef ENTROPY_OPT_SUPPORTED
fprintf(stderr, " -optimize Optimize Huffman table (smaller file, but slow compression, enabled by default)\n");
fprintf(stderr, " -optimize Optimize Huffman table (smaller file, but slow compression)\n");
#endif
#ifdef C_PROGRESSIVE_SUPPORTED
fprintf(stderr, " -progressive Create progressive JPEG file (enabled by default)\n");
fprintf(stderr, " -progressive Create progressive JPEG file\n");
#endif
fprintf(stderr, " -baseline Create baseline JPEG file (disable progressive coding)\n");
#ifdef TARGA_SUPPORTED
@@ -193,54 +253,69 @@ usage (void)
fprintf(stderr, " -tune-ms-ssim Tune trellis optimization for MS-SSIM\n");
fprintf(stderr, "Switches for advanced users:\n");
fprintf(stderr, " -noovershoot Disable black-on-white deringing via overshoot\n");
fprintf(stderr, " -nojfif Do not write JFIF (reduces size by 18 bytes but breaks standards; no known problems in Web browsers)\n");
fprintf(stderr, " -precision N Create JPEG file with N-bit data precision\n");
#ifdef C_LOSSLESS_SUPPORTED
fprintf(stderr, " (N is 8, 12, or 16; default is 8; if N is 16, then -lossless\n");
fprintf(stderr, " must also be specified)\n");
#else
fprintf(stderr, " (N is 8 or 12; default is 8)\n");
#endif
#ifdef C_LOSSLESS_SUPPORTED
fprintf(stderr, " -lossless psv[,Pt] Create lossless JPEG file\n");
#endif
#ifdef C_ARITH_CODING_SUPPORTED
fprintf(stderr, " -arithmetic Use arithmetic coding\n");
#endif
#ifdef DCT_ISLOW_SUPPORTED
fprintf(stderr, " -dct int Use integer DCT method%s\n",
fprintf(stderr, " -dct int Use accurate integer DCT method%s\n",
(JDCT_DEFAULT == JDCT_ISLOW ? " (default)" : ""));
#endif
#ifdef DCT_IFAST_SUPPORTED
fprintf(stderr, " -dct fast Use fast integer DCT (less accurate)%s\n",
fprintf(stderr, " -dct fast Use less accurate integer DCT method [legacy feature]%s\n",
(JDCT_DEFAULT == JDCT_IFAST ? " (default)" : ""));
#endif
#ifdef DCT_FLOAT_SUPPORTED
fprintf(stderr, " -dct float Use floating-point DCT method%s\n",
fprintf(stderr, " -dct float Use floating-point DCT method [legacy feature]%s\n",
(JDCT_DEFAULT == JDCT_FLOAT ? " (default)" : ""));
#endif
fprintf(stderr, " -quant-baseline Use 8-bit quantization table entries for baseline JPEG compatibility\n");
fprintf(stderr, " -quant-table N Use predefined quantization table N:\n");
fprintf(stderr, " - 0 JPEG Annex K\n");
fprintf(stderr, " - 1 Flat\n");
fprintf(stderr, " - 2 Custom, tuned for MS-SSIM\n");
fprintf(stderr, " - 3 ImageMagick table by N. Robidoux\n");
fprintf(stderr, " - 4 Custom, tuned for PSNR-HVS\n");
fprintf(stderr, " - 2 Tuned for MS-SSIM on Kodak image set\n");
fprintf(stderr, " - 3 ImageMagick table by N. Robidoux (default)\n");
fprintf(stderr, " - 4 Tuned for PSNR-HVS on Kodak image set\n");
fprintf(stderr, " - 5 Table from paper by Klein, Silverstein and Carney\n");
fprintf(stderr, " - 6 Table from paper by Watson, Taylor and Borthwick\n");
fprintf(stderr, " - 7 Table from paper by Ahumada, Watson, Peterson\n");
fprintf(stderr, " - 8 Table from paper by Peterson, Ahumada and Watson\n");
fprintf(stderr, " -icc FILE Embed ICC profile contained in FILE\n");
fprintf(stderr, " -restart N Set restart interval in rows, or in blocks with B\n");
#ifdef INPUT_SMOOTHING_SUPPORTED
fprintf(stderr, " -smooth N Smooth dithered input (N=1..100 is strength)\n");
#endif
fprintf(stderr, " -maxmemory N Maximum memory to use (in kbytes)\n");
fprintf(stderr, " -outfile name Specify name for output file\n");
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
fprintf(stderr, " -memdst Compress to memory instead of file (useful for benchmarking)\n");
#endif
fprintf(stderr, " -report Report compression progress\n");
fprintf(stderr, " -strict Treat all warnings as fatal\n");
fprintf(stderr, " -verbose or -debug Emit debug output\n");
fprintf(stderr, " -version Print version information and exit\n");
fprintf(stderr, "Switches for wizards:\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, " -sample HxV[,...] Set component sampling factors\n");
#ifdef C_MULTISCAN_FILES_SUPPORTED
fprintf(stderr, " -scans file Create multi-scan JPEG per script file\n");
fprintf(stderr, " -scans FILE Create multi-scan JPEG per script FILE\n");
#endif
exit(EXIT_FAILURE);
}
LOCAL(int)
parse_switches (j_compress_ptr cinfo, int argc, char **argv,
int last_file_arg_seen, boolean for_real)
parse_switches(j_compress_ptr cinfo, int argc, char **argv,
int last_file_arg_seen, boolean for_real)
/* Parse optional switches.
* Returns argv[] index of first file-name argument (== argc if none).
* Any file names with indexes <= last_file_arg_seen are ignored;
@@ -252,6 +327,9 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
{
int argn;
char *arg;
#ifdef C_LOSSLESS_SUPPORTED
int psv = 0, pt = 0;
#endif
boolean force_baseline;
boolean simple_progressive;
char *qualityarg = NULL; /* saves -quality parm if any */
@@ -269,8 +347,11 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
simple_progressive = FALSE;
#endif
is_targa = FALSE;
icc_filename = NULL;
outfilename = NULL;
memdst = FALSE;
report = FALSE;
strict = FALSE;
cinfo->err->trace_level = 0;
/* Scan command line options, adjust parameters */
@@ -330,10 +411,11 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
/* On first -d, print version identification */
static boolean printed_version = FALSE;
if (! printed_version) {
if (!printed_version) {
fprintf(stderr, "%s version %s (build %s)\n",
PACKAGE_NAME, VERSION, BUILD);
fprintf(stderr, "%s\n\n", JCOPYRIGHT);
fprintf(stderr, JCOPYRIGHT1);
fprintf(stderr, JCOPYRIGHT2 "\n");
fprintf(stderr, "Emulating The Independent JPEG Group's software, version %s\n\n",
JVERSION);
printed_version = TRUE;
@@ -368,6 +450,34 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
jpeg_c_set_float_param(cinfo, JFLOAT_LAMBDA_LOG_SCALE2,
atof(argv[argn]));
} else if (keymatch(arg, "icc", 1)) {
/* Set ICC filename. */
if (++argn >= argc) /* advance to next argument */
usage();
icc_filename = argv[argn];
} else if (keymatch(arg, "lossless", 1)) {
/* Enable lossless mode. */
#ifdef C_LOSSLESS_SUPPORTED
char ch = ',', *ptr;
if (++argn >= argc) /* advance to next argument */
usage();
if (sscanf(argv[argn], "%d%c", &psv, &ch) < 1 || ch != ',')
usage();
ptr = argv[argn];
while (*ptr && *ptr++ != ','); /* advance to next segment of arg
string */
if (*ptr)
sscanf(ptr, "%d", &pt);
/* We must postpone execution until data_precision is known. */
#else
fprintf(stderr, "%s: sorry, lossless output was not compiled\n",
progname);
exit(EXIT_FAILURE);
#endif
} else if (keymatch(arg, "maxmemory", 3)) {
/* Maximum memory in Kb (or Mb with 'm'). */
long lval;
@@ -406,6 +516,22 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
}
outfilename = argv[argn]; /* save it away for later use */
} else if (keymatch(arg, "precision", 3)) {
/* Set data precision. */
int val;
if (++argn >= argc) /* advance to next argument */
usage();
if (sscanf(argv[argn], "%d", &val) != 1)
usage();
#ifdef C_LOSSLESS_SUPPORTED
if (val != 8 && val != 12 && val != 16)
#else
if (val != 8 && val != 12)
#endif
usage();
cinfo->data_precision = val;
} else if (keymatch(arg, "progressive", 1)) {
/* Select simple progressive mode. */
#ifdef C_PROGRESSIVE_SUPPORTED
@@ -419,13 +545,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
} else if (keymatch(arg, "memdst", 2)) {
/* Use in-memory destination manager */
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
memdst = TRUE;
#else
fprintf(stderr, "%s: sorry, in-memory destination manager was not compiled in\n",
progname);
exit(EXIT_FAILURE);
#endif
} else if (keymatch(arg, "quality", 1)) {
/* Quality ratings (quantization table scaling factors). */
@@ -452,6 +572,8 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
qtablefile = argv[argn];
/* We postpone actually reading the file in case -quality comes later. */
} else if (keymatch(arg, "report", 3)) {
report = TRUE;
} else if (keymatch(arg, "quant-table", 7)) {
int val;
if (++argn >= argc) /* advance to next argument */
@@ -467,7 +589,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
} else if (keymatch(arg, "quant-baseline", 7)) {
/* Force quantization table to meet baseline requirements */
force_baseline = TRUE;
} else if (keymatch(arg, "restart", 1)) {
/* Restart interval in MCU rows (or in MCUs with 'b'). */
long lval;
@@ -480,10 +602,10 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
if (lval < 0 || lval > 65535L)
usage();
if (ch == 'b' || ch == 'B') {
cinfo->restart_interval = (unsigned int) lval;
cinfo->restart_interval = (unsigned int)lval;
cinfo->restart_in_rows = 0; /* else prior '-restart n' overrides me */
} else {
cinfo->restart_in_rows = (int) lval;
cinfo->restart_in_rows = (int)lval;
/* restart_interval will be computed during startup */
}
@@ -502,7 +624,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
* default sampling factors.
*/
} else if (keymatch(arg, "scans", 4)) {
} else if (keymatch(arg, "scans", 2)) {
/* Set scan script. */
#ifdef C_MULTISCAN_FILES_SUPPORTED
if (++argn >= argc) /* advance to next argument */
@@ -527,6 +649,9 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
usage();
cinfo->smoothing_factor = val;
} else if (keymatch(arg, "strict", 2)) {
strict = TRUE;
} else if (keymatch(arg, "targa", 1)) {
/* Input file is Targa format. */
is_targa = TRUE;
@@ -580,6 +705,9 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
} else if (keymatch(arg, "noovershoot", 11)) {
jpeg_c_set_bool_param(cinfo, JBOOLEAN_OVERSHOOT_DERINGING, FALSE);
} else if (keymatch(arg, "nojfif", 6)) {
cinfo->write_JFIF_header = 0;
} else {
fprintf(stderr, "%s: unknown option '%s'\n", progname, arg);
usage(); /* bogus switch */
@@ -605,9 +733,11 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
}
if (qslotsarg != NULL) /* process -qslots if it was present */
if (! set_quant_slots(cinfo, qslotsarg))
if (!set_quant_slots(cinfo, qslotsarg))
usage();
/* set_quality_ratings sets default subsampling, so the explicit
subsampling must be set after it */
if (samplearg != NULL) /* process -sample if it was present */
if (! set_sample_factors(cinfo, samplearg)) {
fprintf(stderr, "%s: can't set sample factors\n", progname);
@@ -619,9 +749,14 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
jpeg_simple_progression(cinfo);
#endif
#ifdef C_LOSSLESS_SUPPORTED
if (psv != 0) /* process -lossless */
jpeg_enable_lossless(cinfo, psv, pt);
#endif
#ifdef C_MULTISCAN_FILES_SUPPORTED
if (scansarg != NULL) /* process -scans if it was present */
if (! read_scan_script(cinfo, scansarg))
if (!read_scan_script(cinfo, scansarg))
usage();
#endif
}
@@ -630,31 +765,45 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
}
METHODDEF(void)
my_emit_message(j_common_ptr cinfo, int msg_level)
{
if (msg_level < 0) {
/* Treat warning as fatal */
cinfo->err->error_exit(cinfo);
} else {
if (cinfo->err->trace_level >= msg_level)
cinfo->err->output_message(cinfo);
}
}
/*
* The main program.
*/
int
main (int argc, char **argv)
main(int argc, char **argv)
{
struct jpeg_compress_struct cinfo;
#ifdef CJPEG_FUZZER
struct my_error_mgr myerr;
struct jpeg_error_mgr &jerr = myerr.pub;
#else
struct jpeg_error_mgr jerr;
#ifdef PROGRESS_REPORT
struct cdjpeg_progress_mgr progress;
#endif
struct cdjpeg_progress_mgr progress;
int file_index;
cjpeg_source_ptr src_mgr;
FILE *input_file;
FILE *input_file = NULL;
FILE *icc_file;
JOCTET *icc_profile = NULL;
long icc_len = 0;
FILE *output_file = NULL;
unsigned char *outbuffer = NULL;
unsigned long outsize = 0;
JDIMENSION num_scanlines;
/* On Mac, fetch a command line. */
#ifdef USE_CCOMMAND
argc = ccommand(&argv);
#endif
progname = argv[0];
if (progname == NULL || progname[0] == 0)
progname = "cjpeg"; /* in case C library doesn't provide it */
@@ -684,18 +833,21 @@ main (int argc, char **argv)
file_index = parse_switches(&cinfo, argc, argv, 0, FALSE);
if (strict)
jerr.emit_message = my_emit_message;
#ifdef TWO_FILE_COMMANDLINE
if (!memdst) {
/* Must have either -outfile switch or explicit output file name */
if (outfilename == NULL) {
if (file_index != argc-2) {
if (file_index != argc - 2) {
fprintf(stderr, "%s: must name one input and one output file\n",
progname);
usage();
}
outfilename = argv[file_index+1];
outfilename = argv[file_index + 1];
} else {
if (file_index != argc-1) {
if (file_index != argc - 1) {
fprintf(stderr, "%s: must name one input and one output file\n",
progname);
usage();
@@ -704,7 +856,7 @@ main (int argc, char **argv)
}
#else
/* Unix style: expect zero or one file name */
if (file_index < argc-1) {
if (file_index < argc - 1) {
fprintf(stderr, "%s: only one input file\n", progname);
usage();
}
@@ -732,13 +884,51 @@ main (int argc, char **argv)
output_file = write_stdout();
}
#ifdef PROGRESS_REPORT
start_progress_monitor((j_common_ptr) &cinfo, &progress);
if (icc_filename != NULL) {
if ((icc_file = fopen(icc_filename, READ_BINARY)) == NULL) {
fprintf(stderr, "%s: can't open %s\n", progname, icc_filename);
exit(EXIT_FAILURE);
}
if (fseek(icc_file, 0, SEEK_END) < 0 ||
(icc_len = ftell(icc_file)) < 1 ||
fseek(icc_file, 0, SEEK_SET) < 0) {
fprintf(stderr, "%s: can't determine size of %s\n", progname,
icc_filename);
exit(EXIT_FAILURE);
}
if ((icc_profile = (JOCTET *)malloc(icc_len)) == NULL) {
fprintf(stderr, "%s: can't allocate memory for ICC profile\n", progname);
fclose(icc_file);
exit(EXIT_FAILURE);
}
if (fread(icc_profile, icc_len, 1, icc_file) < 1) {
fprintf(stderr, "%s: can't read ICC profile from %s\n", progname,
icc_filename);
free(icc_profile);
fclose(icc_file);
exit(EXIT_FAILURE);
}
fclose(icc_file);
}
#ifdef CJPEG_FUZZER
jerr.error_exit = my_error_exit;
jerr.emit_message = my_emit_message_fuzzer;
if (setjmp(myerr.setjmp_buffer))
HANDLE_ERROR()
#endif
if (report) {
start_progress_monitor((j_common_ptr)&cinfo, &progress);
progress.report = report;
}
/* Figure out the input file format, and set up to read it. */
src_mgr = select_file_type(&cinfo, input_file);
src_mgr->input_file = input_file;
#ifdef CJPEG_FUZZER
src_mgr->max_pixels = 1048576;
#endif
/* Read the input file header to obtain file size & colorspace. */
(*src_mgr->start_input) (&cinfo, src_mgr);
@@ -753,18 +943,21 @@ main (int argc, char **argv)
file_index = parse_switches(&cinfo, argc, argv, 0, TRUE);
/* Specify data destination for compression */
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
if (memdst)
jpeg_mem_dest(&cinfo, &outbuffer, &outsize);
else
#endif
jpeg_stdio_dest(&cinfo, output_file);
#ifdef CJPEG_FUZZER
if (setjmp(myerr.setjmp_buffer))
HANDLE_ERROR()
#endif
/* Start compressor */
jpeg_start_compress(&cinfo, TRUE);
/* Copy metadata */
if (is_jpeg) {
if (copy_markers) {
jpeg_saved_marker_ptr marker;
/* In the current implementation, we don't actually need to examine the
@@ -795,8 +988,25 @@ main (int argc, char **argv)
marker->data_length);
}
}
if (icc_profile != NULL)
jpeg_write_icc_profile(&cinfo, icc_profile, (unsigned int)icc_len);
/* Process data */
if (cinfo.data_precision == 16) {
#ifdef C_LOSSLESS_SUPPORTED
while (cinfo.next_scanline < cinfo.image_height) {
num_scanlines = (*src_mgr->get_pixel_rows) (&cinfo, src_mgr);
(void)jpeg16_write_scanlines(&cinfo, src_mgr->buffer16, num_scanlines);
}
#else
ERREXIT1(&cinfo, JERR_BAD_PRECISION, cinfo.data_precision);
#endif
} else if (cinfo.data_precision == 12) {
while (cinfo.next_scanline < cinfo.image_height) {
num_scanlines = (*src_mgr->get_pixel_rows) (&cinfo, src_mgr);
(void)jpeg12_write_scanlines(&cinfo, src_mgr->buffer12, num_scanlines);
}
} else {
while (cinfo.next_scanline < cinfo.image_height) {
num_scanlines = (*src_mgr->get_pixel_rows) (&cinfo, src_mgr);
#if JPEG_RAW_READER
@@ -804,7 +1014,8 @@ main (int argc, char **argv)
(void) jpeg_write_raw_data(&cinfo, src_mgr->plane_pointer, num_scanlines);
else
#endif
(void) jpeg_write_scanlines(&cinfo, src_mgr->buffer, num_scanlines);
(void)jpeg_write_scanlines(&cinfo, src_mgr->buffer, num_scanlines);
}
}
/* Finish compression and release memory */
@@ -818,17 +1029,18 @@ main (int argc, char **argv)
if (output_file != stdout && output_file != NULL)
fclose(output_file);
#ifdef PROGRESS_REPORT
end_progress_monitor((j_common_ptr) &cinfo);
#endif
if (report)
end_progress_monitor((j_common_ptr)&cinfo);
if (memdst) {
#ifndef CJPEG_FUZZER
fprintf(stderr, "Compressed size: %lu bytes\n", outsize);
if (outbuffer != NULL)
free(outbuffer);
#endif
free(outbuffer);
}
free(icc_profile);
/* All done. */
exit(jerr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS);
return 0; /* suppress no-return-value warnings */
return (jerr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS);
}

View File

@@ -0,0 +1,176 @@
# This file is included from the top-level CMakeLists.txt. We just store it
# here to avoid cluttering up that file.
###############################################################################
# Linux RPM and DEB
###############################################################################
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(RPMARCH ${CMAKE_SYSTEM_PROCESSOR})
if(CPU_TYPE STREQUAL "x86_64")
set(DEBARCH amd64)
elseif(CPU_TYPE STREQUAL "arm64")
set(DEBARCH ${CPU_TYPE})
elseif(CPU_TYPE STREQUAL "arm")
check_c_source_compiles("
#if __ARM_PCS_VFP != 1
#error \"float ABI != hard\"
#endif
int main(void) { return 0; }" HAVE_HARD_FLOAT)
if(HAVE_HARD_FLOAT)
set(RPMARCH armv7hl)
set(DEBARCH armhf)
else()
set(RPMARCH armel)
set(DEBARCH armel)
endif()
elseif(CMAKE_SYSTEM_PROCESSOR_LC STREQUAL "ppc64le")
set(DEBARCH ppc64el)
elseif(CPU_TYPE STREQUAL "powerpc" AND BITS EQUAL 32)
set(RPMARCH ppc)
set(DEBARCH ppc)
else()
set(DEBARCH ${CMAKE_SYSTEM_PROCESSOR})
endif()
message(STATUS "RPM architecture = ${RPMARCH}, DEB architecture = ${DEBARCH}")
# Re-set CMAKE_POSITION_INDEPENDENT_CODE so that the RPM spec file works
# properly
boolean_number(CMAKE_POSITION_INDEPENDENT_CODE)
configure_file(release/makerpm.in pkgscripts/makerpm)
configure_file(release/rpm.spec.in pkgscripts/rpm.spec @ONLY)
add_custom_target(rpm pkgscripts/makerpm
SOURCES pkgscripts/makerpm)
configure_file(release/makesrpm.in pkgscripts/makesrpm)
add_custom_target(srpm pkgscripts/makesrpm
SOURCES pkgscripts/makesrpm
DEPENDS dist)
configure_file(release/makedpkg.in pkgscripts/makedpkg)
configure_file(release/deb-control.in pkgscripts/deb-control)
add_custom_target(deb pkgscripts/makedpkg
SOURCES pkgscripts/makedpkg)
endif() # Linux
###############################################################################
# Windows installer (NullSoft Installer)
###############################################################################
if(WIN32)
if(MSVC_LIKE)
set(INST_PLATFORM "Visual C++")
set(INST_ID vc)
set(INST_NAME ${CMAKE_PROJECT_NAME}-${VERSION}-${INST_ID})
set(INST_REG_NAME ${CMAKE_PROJECT_NAME})
elseif(MINGW)
set(INST_PLATFORM GCC)
set(INST_ID gcc)
set(INST_NAME ${CMAKE_PROJECT_NAME}-${VERSION}-${INST_ID})
set(INST_REG_NAME ${CMAKE_PROJECT_NAME}-${INST_ID})
set(INST_DEFS -DGCC)
endif()
if(BITS EQUAL 64)
set(INST_PLATFORM "${INST_PLATFORM} 64-bit")
set(INST_NAME ${INST_NAME}64)
set(INST_REG_NAME ${INST_REG_NAME}64)
set(INST_DEFS ${INST_DEFS} -DWIN64)
endif()
if(WITH_JAVA)
set(INST_DEFS ${INST_DEFS} -DJAVA)
endif()
if(GENERATOR_IS_MULTI_CONFIG)
set(INST_DEFS ${INST_DEFS} "-DBUILDDIR=${CMAKE_CFG_INTDIR}\\")
else()
set(INST_DEFS ${INST_DEFS} "-DBUILDDIR=")
endif()
string(REGEX REPLACE "/" "\\\\" INST_DIR ${CMAKE_INSTALL_PREFIX})
configure_file(release/installer.nsi.in installer.nsi @ONLY)
# TODO: It would be nice to eventually switch to CPack and eliminate this mess,
# but not today.
configure_file(win/projectTargets.cmake.in
win/${CMAKE_PROJECT_NAME}Targets.cmake @ONLY)
configure_file(win/${INST_ID}/projectTargets-release.cmake.in
win/${CMAKE_PROJECT_NAME}Targets-release.cmake @ONLY)
if(WITH_JAVA)
set(JAVA_DEPEND turbojpeg-java)
endif()
if(WITH_TURBOJPEG)
set(TURBOJPEG_DEPEND turbojpeg turbojpeg-static tjbench)
endif()
add_custom_target(installer
makensis -nocd ${INST_DEFS} installer.nsi
DEPENDS jpeg jpeg-static rdjpgcom wrjpgcom cjpeg djpeg jpegtran
${JAVA_DEPEND} ${TURBOJPEG_DEPEND}
SOURCES installer.nsi)
endif() # WIN32
###############################################################################
# Mac DMG
###############################################################################
if(APPLE)
set(SECONDARY_BUILD "" CACHE PATH
"Directory containing cross-compiled x86-64 or Armv8 (64-bit) iOS or macOS build to include in universal binaries")
set(MACOS_APP_CERT_NAME "" CACHE STRING
"Name of the Developer ID Application certificate (in the macOS keychain) that should be used to sign the libjpeg-turbo DMG. Leave this blank to generate an unsigned DMG.")
set(MACOS_INST_CERT_NAME "" CACHE STRING
"Name of the Developer ID Installer certificate (in the macOS keychain) that should be used to sign the libjpeg-turbo installer package. Leave this blank to generate an unsigned package.")
configure_file(release/makemacpkg.in pkgscripts/makemacpkg)
configure_file(release/Distribution.xml.in pkgscripts/Distribution.xml)
configure_file(release/Welcome.rtf.in pkgscripts/Welcome.rtf)
configure_file(release/uninstall.in pkgscripts/uninstall)
add_custom_target(dmg pkgscripts/makemacpkg
SOURCES pkgscripts/makemacpkg)
endif() # APPLE
###############################################################################
# Generic
###############################################################################
add_custom_target(dist
COMMAND git archive --prefix=${CMAKE_PROJECT_NAME}-${VERSION}/ HEAD |
gzip > ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}-${VERSION}.tar.gz
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
configure_file(release/maketarball.in pkgscripts/maketarball)
add_custom_target(tarball pkgscripts/maketarball
SOURCES pkgscripts/maketarball)
configure_file(release/libjpeg.pc.in pkgscripts/libjpeg.pc @ONLY)
if(WITH_TURBOJPEG)
configure_file(release/libturbojpeg.pc.in pkgscripts/libturbojpeg.pc @ONLY)
endif()
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
pkgscripts/${CMAKE_PROJECT_NAME}ConfigVersion.cmake
VERSION ${VERSION} COMPATIBILITY AnyNewerVersion)
configure_package_config_file(release/Config.cmake.in
pkgscripts/${CMAKE_PROJECT_NAME}Config.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${CMAKE_PROJECT_NAME})

View File

@@ -0,0 +1,424 @@
#.rst:
# GNUInstallDirs
# --------------
#
# Define GNU standard installation directories
#
# Provides install directory variables as defined by the
# `GNU Coding Standards`_.
#
# .. _`GNU Coding Standards`: https://www.gnu.org/prep/standards/html_node/Directory-Variables.html
#
# Result Variables
# ^^^^^^^^^^^^^^^^
#
# Inclusion of this module defines the following variables:
#
# ``CMAKE_INSTALL_<dir>``
#
# Destination for files of a given type. This value may be passed to
# the ``DESTINATION`` options of :command:`install` commands for the
# corresponding file type.
#
# ``CMAKE_INSTALL_FULL_<dir>``
#
# The absolute path generated from the corresponding ``CMAKE_INSTALL_<dir>``
# value. If the value is not already an absolute path, an absolute path
# is constructed typically by prepending the value of the
# :variable:`CMAKE_INSTALL_PREFIX` variable. However, there are some
# `special cases`_ as documented below.
#
# where ``<dir>`` is one of:
#
# ``BINDIR``
# user executables (``bin``)
# ``SBINDIR``
# system admin executables (``sbin``)
# ``LIBEXECDIR``
# program executables (``libexec``)
# ``SYSCONFDIR``
# read-only single-machine data (``etc``)
# ``SHAREDSTATEDIR``
# modifiable architecture-independent data (``com``)
# ``LOCALSTATEDIR``
# modifiable single-machine data (``var``)
# ``LIBDIR``
# object code libraries (``lib`` or ``lib64``
# or ``lib/<multiarch-tuple>`` on Debian)
# ``INCLUDEDIR``
# C header files (``include``)
# ``OLDINCLUDEDIR``
# C header files for non-gcc (``/usr/include``)
# ``DATAROOTDIR``
# read-only architecture-independent data root (``share``)
# ``DATADIR``
# read-only architecture-independent data (``DATAROOTDIR``)
# ``INFODIR``
# info documentation (``DATAROOTDIR/info``)
# ``LOCALEDIR``
# locale-dependent data (``DATAROOTDIR/locale``)
# ``MANDIR``
# man documentation (``DATAROOTDIR/man``)
# ``DOCDIR``
# documentation root (``DATAROOTDIR/doc/PROJECT_NAME``)
#
# If the includer does not define a value the above-shown default will be
# used and the value will appear in the cache for editing by the user.
#
# Special Cases
# ^^^^^^^^^^^^^
#
# The following values of :variable:`CMAKE_INSTALL_PREFIX` are special:
#
# ``/``
#
# For ``<dir>`` other than the ``SYSCONFDIR`` and ``LOCALSTATEDIR``,
# the value of ``CMAKE_INSTALL_<dir>`` is prefixed with ``usr/`` if
# it is not user-specified as an absolute path. For example, the
# ``INCLUDEDIR`` value ``include`` becomes ``usr/include``.
# This is required by the `GNU Coding Standards`_, which state:
#
# When building the complete GNU system, the prefix will be empty
# and ``/usr`` will be a symbolic link to ``/``.
#
# ``/usr``
#
# For ``<dir>`` equal to ``SYSCONFDIR`` or ``LOCALSTATEDIR``, the
# ``CMAKE_INSTALL_FULL_<dir>`` is computed by prepending just ``/``
# to the value of ``CMAKE_INSTALL_<dir>`` if it is not user-specified
# as an absolute path. For example, the ``SYSCONFDIR`` value ``etc``
# becomes ``/etc``. This is required by the `GNU Coding Standards`_.
#
# ``/opt/...``
#
# For ``<dir>`` equal to ``SYSCONFDIR`` or ``LOCALSTATEDIR``, the
# ``CMAKE_INSTALL_FULL_<dir>`` is computed by *appending* the prefix
# to the value of ``CMAKE_INSTALL_<dir>`` if it is not user-specified
# as an absolute path. For example, the ``SYSCONFDIR`` value ``etc``
# becomes ``/etc/opt/...``. This is defined by the
# `Filesystem Hierarchy Standard`_.
#
# .. _`Filesystem Hierarchy Standard`: https://refspecs.linuxfoundation.org/FHS_3.0/fhs/index.html
#
# Macros
# ^^^^^^
#
# .. command:: GNUInstallDirs_get_absolute_install_dir
#
# ::
#
# GNUInstallDirs_get_absolute_install_dir(absvar var)
#
# Set the given variable ``absvar`` to the absolute path contained
# within the variable ``var``. This is to allow the computation of an
# absolute path, accounting for all the special cases documented
# above. While this macro is used to compute the various
# ``CMAKE_INSTALL_FULL_<dir>`` variables, it is exposed publicly to
# allow users who create additional path variables to also compute
# absolute paths where necessary, using the same logic.
#=============================================================================
# Copyright 2018 Tobias C. Berner
# Copyright 2018 Matthias Räncker
# Copyright 2016, 2019, 2024 D. R. Commander
# Copyright 2016, 2021 Dmitry Marakasov
# Copyright 2016 Roger Leigh
# Copyright 2015 Alex Turbov
# Copyright 2014 Rolf Eike Beer
# Copyright 2014 Daniele E. Domenichelli
# Copyright 2013 Dimitri John Ledkov
# Copyright 2011 Alex Neundorf
# Copyright 2011 Eric NOULARD
# Copyright 2011, 2013-2015 Kitware, Inc.
# Copyright 2011 Nikita Krupen'ko
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# * Neither the names of Kitware, Inc., the Insight Software Consortium,
# nor the names of their contributors may be used to endorse or promote
# products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#=============================================================================
# Installation directories
#
macro(GNUInstallDirs_set_install_dir var docstring)
# If CMAKE_INSTALL_PREFIX changes and CMAKE_INSTALL_*DIR is still set to the
# default value, then modify it accordingly. This presumes that the default
# value may change based on the prefix.
set(_GNUInstallDirs_CMAKE_INSTALL_FORCE_${var} "")
if(NOT DEFINED CMAKE_INSTALL_${var})
set(_GNUInstallDirs_CMAKE_INSTALL_DEFAULT_${var} 1 CACHE INTERNAL
"CMAKE_INSTALL_${var} has default value")
elseif(DEFINED _GNUInstallDirs_CMAKE_INSTALL_LAST_DEFAULT_${var} AND
NOT "${_GNUInstallDirs_CMAKE_INSTALL_LAST_DEFAULT_${var}}" STREQUAL
"${CMAKE_INSTALL_DEFAULT_${var}}" AND
_GNUInstallDirs_CMAKE_INSTALL_DEFAULT_${var} AND
"${_GNUInstallDirs_CMAKE_INSTALL_LAST_${var}}" STREQUAL
"${CMAKE_INSTALL_${var}}")
set(_GNUInstallDirs_CMAKE_INSTALL_FORCE_${var} "FORCE")
endif()
if(DEFINED CMAKE_INSTALL_${var} AND NOT CMAKE_INSTALL_${var} MATCHES "^/")
set_property(CACHE CMAKE_INSTALL_${var} PROPERTY TYPE PATH)
endif()
set(CMAKE_INSTALL_${var} "${CMAKE_INSTALL_DEFAULT_${var}}" CACHE PATH
"${docstring} (Default: ${CMAKE_INSTALL_DEFAULT_${var}})"
${_GNUInstallDirs_CMAKE_INSTALL_FORCE_${var}})
if(NOT CMAKE_INSTALL_${var} STREQUAL CMAKE_INSTALL_DEFAULT_${var})
unset(_GNUInstallDirs_CMAKE_INSTALL_DEFAULT_${var} CACHE)
endif()
# Save for next run
set(_GNUInstallDirs_CMAKE_INSTALL_LAST_${var} "${CMAKE_INSTALL_${var}}"
CACHE INTERNAL "CMAKE_INSTALL_${var} during last run")
set(_GNUInstallDirs_CMAKE_INSTALL_LAST_DEFAULT_${var}
"${CMAKE_INSTALL_DEFAULT_${var}}" CACHE INTERNAL
"CMAKE_INSTALL_DEFAULT_${var} during last run")
endmacro()
if(NOT DEFINED CMAKE_INSTALL_DEFAULT_BINDIR)
set(CMAKE_INSTALL_DEFAULT_BINDIR "bin")
endif()
GNUInstallDirs_set_install_dir(BINDIR
"Directory into which user executables should be installed")
if(NOT DEFINED CMAKE_INSTALL_DEFAULT_SBINDIR)
set(CMAKE_INSTALL_DEFAULT_SBINDIR "sbin")
endif()
GNUInstallDirs_set_install_dir(SBINDIR
"Directory into which system admin executables should be installed")
if(NOT DEFINED CMAKE_INSTALL_DEFAULT_LIBEXECDIR)
set(CMAKE_INSTALL_DEFAULT_LIBEXECDIR "libexec")
endif()
GNUInstallDirs_set_install_dir(LIBEXECDIR
"Directory under which executables run by other programs should be installed")
if(NOT DEFINED CMAKE_INSTALL_DEFAULT_SYSCONFDIR)
set(CMAKE_INSTALL_DEFAULT_SYSCONFDIR "etc")
endif()
GNUInstallDirs_set_install_dir(SYSCONFDIR
"Directory into which machine-specific read-only ASCII data and configuration files should be installed")
if(NOT DEFINED CMAKE_INSTALL_DEFAULT_SHAREDSTATEDIR)
set(CMAKE_INSTALL_DEFAULT_SHAREDSTATEDIR "com")
endif()
GNUInstallDirs_set_install_dir(SHAREDSTATEDIR
"Directory into which architecture-independent run-time-modifiable data files should be installed")
if(NOT DEFINED CMAKE_INSTALL_DEFAULT_LOCALSTATEDIR)
set(CMAKE_INSTALL_DEFAULT_LOCALSTATEDIR "var")
endif()
GNUInstallDirs_set_install_dir(LOCALSTATEDIR
"Directory into which machine-specific run-time-modifiable data files should be installed")
if(NOT DEFINED CMAKE_INSTALL_DEFAULT_LIBDIR)
set(CMAKE_INSTALL_DEFAULT_LIBDIR "lib")
# Override this default 'lib' with 'lib64' iff:
# - we are on Linux system but NOT cross-compiling
# - we are NOT on debian
# - we are on a 64 bits system
# reason is: amd64 ABI: http://www.x86-64.org/documentation/abi.pdf
# For Debian with multiarch, use 'lib/${CMAKE_LIBRARY_ARCHITECTURE}' if
# CMAKE_LIBRARY_ARCHITECTURE is set (which contains e.g. "i386-linux-gnu"
# and CMAKE_INSTALL_PREFIX is "/usr"
# See http://wiki.debian.org/Multiarch
if(CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU)$"
AND NOT CMAKE_CROSSCOMPILING)
if (EXISTS "/etc/debian_version") # is this a debian system ?
if(CMAKE_LIBRARY_ARCHITECTURE)
if("${CMAKE_INSTALL_PREFIX}" MATCHES "^/usr/?$")
set(CMAKE_INSTALL_DEFAULT_LIBDIR "lib/${CMAKE_LIBRARY_ARCHITECTURE}")
endif()
endif()
else() # not debian, rely on CMAKE_SIZEOF_VOID_P:
if(NOT DEFINED CMAKE_SIZEOF_VOID_P)
message(AUTHOR_WARNING
"Unable to determine default CMAKE_INSTALL_LIBDIR directory because no target architecture is known. "
"Please enable at least one language before including GNUInstallDirs.")
else()
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
set(CMAKE_INSTALL_DEFAULT_LIBDIR "lib64")
elseif(CMAKE_C_COMPILER_ABI MATCHES "ELF X32")
set(CMAKE_INSTALL_DEFAULT_LIBDIR "libx32")
endif()
endif()
endif()
endif()
endif()
GNUInstallDirs_set_install_dir(LIBDIR
"Directory into which object files and object code libraries should be installed")
if(NOT DEFINED CMAKE_INSTALL_DEFAULT_INCLUDEDIR)
set(CMAKE_INSTALL_DEFAULT_INCLUDEDIR "include")
endif()
GNUInstallDirs_set_install_dir(INCLUDEDIR
"Directory into which C header files should be installed")
if(NOT DEFINED CMAKE_INSTALL_DEFAULT_OLDINCLUDEDIR)
set(CMAKE_INSTALL_DEFAULT_OLDINCLUDEDIR "/usr/include")
endif()
GNUInstallDirs_set_install_dir(OLDINCLUDEDIR
PATH "Directory into which C header files for non-GCC compilers should be installed")
if(NOT DEFINED CMAKE_INSTALL_DEFAULT_DATAROOTDIR)
set(CMAKE_INSTALL_DEFAULT_DATAROOTDIR "share")
endif()
GNUInstallDirs_set_install_dir(DATAROOTDIR
"The root of the directory tree for read-only architecture-independent data files")
#-----------------------------------------------------------------------------
# Values whose defaults are relative to DATAROOTDIR. Store empty values in
# the cache and store the defaults in local variables if the cache values are
# not set explicitly. This auto-updates the defaults as DATAROOTDIR changes.
if(NOT DEFINED CMAKE_INSTALL_DEFAULT_DATADIR)
set(CMAKE_INSTALL_DEFAULT_DATADIR "<CMAKE_INSTALL_DATAROOTDIR>")
endif()
GNUInstallDirs_set_install_dir(DATADIR
"The directory under which read-only architecture-independent data files should be installed")
if(NOT DEFINED CMAKE_INSTALL_DEFAULT_INFODIR)
if(CMAKE_SYSTEM_NAME MATCHES "^(([^kF].*)?BSD|DragonFly)$")
set(CMAKE_INSTALL_DEFAULT_INFODIR "info")
else()
set(CMAKE_INSTALL_DEFAULT_INFODIR "<CMAKE_INSTALL_DATAROOTDIR>/info")
endif()
endif()
GNUInstallDirs_set_install_dir(INFODIR
"The directory into which info documentation files should be installed")
if(NOT DEFINED CMAKE_INSTALL_DEFAULT_MANDIR)
if(CMAKE_SYSTEM_NAME MATCHES "^(([^k].*)?BSD|DragonFly)$" AND NOT CMAKE_SYSTEM_NAME MATCHES "^(FreeBSD)$")
set(CMAKE_INSTALL_DEFAULT_MANDIR "man")
else()
set(CMAKE_INSTALL_DEFAULT_MANDIR "<CMAKE_INSTALL_DATAROOTDIR>/man")
endif()
endif()
GNUInstallDirs_set_install_dir(MANDIR
"The directory under which man pages should be installed")
if(NOT DEFINED CMAKE_INSTALL_DEFAULT_LOCALEDIR)
set(CMAKE_INSTALL_DEFAULT_LOCALEDIR "<CMAKE_INSTALL_DATAROOTDIR>/locale")
endif()
GNUInstallDirs_set_install_dir(LOCALEDIR
"The directory under which locale-specific message catalogs should be installed")
if(NOT DEFINED CMAKE_INSTALL_DEFAULT_DOCDIR)
set(CMAKE_INSTALL_DEFAULT_DOCDIR "<CMAKE_INSTALL_DATAROOTDIR>/doc/${PROJECT_NAME}")
endif()
GNUInstallDirs_set_install_dir(DOCDIR
"The directory into which documentation files (other than info files) should be installed")
#-----------------------------------------------------------------------------
mark_as_advanced(
CMAKE_INSTALL_BINDIR
CMAKE_INSTALL_SBINDIR
CMAKE_INSTALL_LIBEXECDIR
CMAKE_INSTALL_SYSCONFDIR
CMAKE_INSTALL_SHAREDSTATEDIR
CMAKE_INSTALL_LOCALSTATEDIR
CMAKE_INSTALL_LIBDIR
CMAKE_INSTALL_INCLUDEDIR
CMAKE_INSTALL_OLDINCLUDEDIR
CMAKE_INSTALL_DATAROOTDIR
CMAKE_INSTALL_DATADIR
CMAKE_INSTALL_INFODIR
CMAKE_INSTALL_LOCALEDIR
CMAKE_INSTALL_MANDIR
CMAKE_INSTALL_DOCDIR
)
macro(GNUInstallDirs_get_absolute_install_dir absvar var)
string(REGEX REPLACE "[<>]" "@" ${var} "${${var}}")
# Handle the specific case of an empty CMAKE_INSTALL_DATAROOTDIR
if(NOT CMAKE_INSTALL_DATAROOTDIR AND
${var} MATCHES "\@CMAKE_INSTALL_DATAROOTDIR\@/")
string(CONFIGURE "${${var}}" ${var} @ONLY)
string(REGEX REPLACE "^/" "" ${var} "${${var}}")
else()
string(CONFIGURE "${${var}}" ${var} @ONLY)
endif()
if(NOT IS_ABSOLUTE "${${var}}")
# Handle special cases:
# - CMAKE_INSTALL_PREFIX == /
# - CMAKE_INSTALL_PREFIX == /usr
# - CMAKE_INSTALL_PREFIX == /opt/...
if("${CMAKE_INSTALL_PREFIX}" STREQUAL "/")
if("${dir}" STREQUAL "SYSCONFDIR" OR "${dir}" STREQUAL "LOCALSTATEDIR")
set(${absvar} "/${${var}}")
else()
if (NOT "${${var}}" MATCHES "^usr/")
set(${var} "usr/${${var}}")
endif()
set(${absvar} "/${${var}}")
endif()
elseif("${CMAKE_INSTALL_PREFIX}" MATCHES "^/usr/?$")
if("${dir}" STREQUAL "SYSCONFDIR" OR "${dir}" STREQUAL "LOCALSTATEDIR")
set(${absvar} "/${${var}}")
else()
set(${absvar} "${CMAKE_INSTALL_PREFIX}/${${var}}")
endif()
elseif("${CMAKE_INSTALL_PREFIX}" MATCHES "^/opt/.*")
if("${dir}" STREQUAL "SYSCONFDIR" OR "${dir}" STREQUAL "LOCALSTATEDIR")
set(${absvar} "/${${var}}${CMAKE_INSTALL_PREFIX}")
else()
set(${absvar} "${CMAKE_INSTALL_PREFIX}/${${var}}")
endif()
else()
set(${absvar} "${CMAKE_INSTALL_PREFIX}/${${var}}")
endif()
else()
set(${absvar} "${${var}}")
endif()
string(REGEX REPLACE "/$" "" ${absvar} "${${absvar}}")
endmacro()
# Result directories
#
foreach(dir
BINDIR
SBINDIR
LIBEXECDIR
SYSCONFDIR
SHAREDSTATEDIR
LOCALSTATEDIR
LIBDIR
INCLUDEDIR
OLDINCLUDEDIR
DATAROOTDIR
DATADIR
INFODIR
LOCALEDIR
MANDIR
DOCDIR
)
GNUInstallDirs_get_absolute_install_dir(CMAKE_INSTALL_FULL_${dir} CMAKE_INSTALL_${dir})
endforeach()

View File

@@ -0,0 +1,13 @@
# This file is included from the top-level CMakeLists.txt. We just store it
# here to avoid cluttering up that file.
set(PKGNAME ${CMAKE_PROJECT_NAME} CACHE STRING
"Distribution package name (default: ${CMAKE_PROJECT_NAME})")
set(PKGVENDOR "The ${CMAKE_PROJECT_NAME} Project" CACHE STRING
"Vendor name to be included in distribution package descriptions (default: The ${CMAKE_PROJECT_NAME} Project)")
set(PKGURL "https://${CMAKE_PROJECT_NAME}.org" CACHE STRING
"URL of project web site to be included in distribution package descriptions (default: https://${CMAKE_PROJECT_NAME}.org)")
set(PKGEMAIL "information@${CMAKE_PROJECT_NAME}.org" CACHE STRING
"E-mail of project maintainer to be included in distribution package descriptions (default: information@${CMAKE_PROJECT_NAME}.org")
set(PKGID "com.${CMAKE_PROJECT_NAME}.${PKGNAME}" CACHE STRING
"Globally unique package identifier (reverse DNS notation) (default: com.${CMAKE_PROJECT_NAME}.${PKGNAME})")

View File

@@ -0,0 +1,24 @@
# This code is from the CMake FAQ
if (NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_BINARY_DIR@/install_manifest.txt\"")
endif(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files)
string(REGEX REPLACE "\n" ";" files "${files}")
list(REVERSE files)
foreach (file ${files})
message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
if (EXISTS "$ENV{DESTDIR}${file}")
execute_process(
COMMAND "@CMAKE_COMMAND@" -E remove "$ENV{DESTDIR}${file}"
OUTPUT_VARIABLE rm_out
RESULT_VARIABLE rm_retval
)
if(NOT ${rm_retval} EQUAL 0)
message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
endif (NOT ${rm_retval} EQUAL 0)
else (EXISTS "$ENV{DESTDIR}${file}")
message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
endif (EXISTS "$ENV{DESTDIR}${file}")
endforeach(file)

View File

@@ -24,7 +24,23 @@ file(GLOB FILES
*_440_*.png
*_440_*.ppm
*_440_*.jpg
*_440.yuv)
*_440.yuv
*_411_*.bmp
*_411_*.png
*_411_*.ppm
*_411_*.jpg
*_411.yuv
*_441_*.bmp
*_441_*.png
*_441_*.ppm
*_441_*.jpg
*_441.yuv
*_LOSSL*S_*.bmp
*_LOSSL*S_*.ppm
*_LOSSL*S_*.jpg
croptest.log
tjbenchtest*.log
tjexampletest*.log)
if(NOT FILES STREQUAL "")
message(STATUS "Removing test files")

View File

@@ -0,0 +1,77 @@
if(NOT DEFINED PRECISION)
message(FATAL_ERROR "PRECISION must be specified")
endif()
if(NOT DEFINED WITH_JAVA)
message(FATAL_ERROR "WITH_JAVA must be specified")
endif()
macro(check_error program)
if(NOT RESULT EQUAL 0)
message(FATAL_ERROR "${program} failed.")
endif()
endmacro()
macro(run_test PROG ARGS)
string(REPLACE ";" " " SPACED_ARGS "${ARGS}")
message(STATUS "${PROG} ${SPACED_ARGS}")
execute_process(COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${PROG} ${ARGS}
RESULT_VARIABLE RESULT)
check_error("${PROG} ${SPACED_ARGS}")
endmacro()
if(NOT PRECISION EQUAL 16)
run_test(tjbenchtest "-precision;${PRECISION}")
run_test(tjbenchtest "-precision;${PRECISION};-alloc")
endif()
if(PRECISION EQUAL 8)
run_test(tjbenchtest "-precision;${PRECISION};-yuv")
run_test(tjbenchtest "-precision;${PRECISION};-yuv;-alloc")
run_test(tjbenchtest "-precision;${PRECISION};-optimize")
run_test(tjbenchtest "-precision;${PRECISION};-optimize;-yuv")
endif()
if(NOT PRECISION EQUAL 16)
run_test(tjbenchtest "-precision;${PRECISION};-progressive")
endif()
if(PRECISION EQUAL 8)
run_test(tjbenchtest "-precision;${PRECISION};-progressive;-yuv")
endif()
if(NOT PRECISION EQUAL 16)
run_test(tjbenchtest "-precision;${PRECISION};-arithmetic")
run_test(tjbenchtest "-precision;${PRECISION};-progressive;-arithmetic")
endif()
if(PRECISION EQUAL 8)
run_test(tjbenchtest "-precision;${PRECISION};-arithmetic;-yuv")
endif()
run_test(tjbenchtest "-precision;${PRECISION};-lossless")
run_test(tjbenchtest "-precision;${PRECISION};-lossless;-alloc")
if(PRECISION EQUAL 8)
run_test(tjexampletest "")
endif()
if(WITH_JAVA)
if(NOT PRECISION EQUAL 16)
run_test(tjbenchtest "-java;-precision;${PRECISION}")
endif()
if(PRECISION EQUAL 8)
run_test(tjbenchtest "-java;-precision;${PRECISION};-yuv")
run_test(tjbenchtest "-java;-precision;${PRECISION};-optimize")
run_test(tjbenchtest "-java;-precision;${PRECISION};-optimize;-yuv")
endif()
if(NOT PRECISION EQUAL 16)
run_test(tjbenchtest "-java;-precision;${PRECISION};-progressive")
endif()
if(PRECISION EQUAL 8)
run_test(tjbenchtest "-java;-precision;${PRECISION};-progressive;-yuv")
endif()
if(NOT PRECISION EQUAL 16)
run_test(tjbenchtest "-java;-precision;${PRECISION};-arithmetic")
run_test(tjbenchtest "-java;-precision;${PRECISION};-progressive;-arithmetic")
endif()
if(PRECISION EQUAL 8)
run_test(tjbenchtest "-java;-precision;${PRECISION};-arithmetic;-yuv")
endif()
run_test(tjbenchtest "-java;-precision;${PRECISION};-lossless")
if(PRECISION EQUAL 8)
run_test(tjexampletest "-java")
endif()
endif()

61
cmyk.h Normal file
View File

@@ -0,0 +1,61 @@
/*
* cmyk.h
*
* Copyright (C) 2017-2018, 2022, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
* This file contains convenience functions for performing quick & dirty
* CMYK<->RGB conversion. This algorithm is suitable for testing purposes
* only. Properly converting between CMYK and RGB requires a color management
* system.
*/
#ifndef CMYK_H
#define CMYK_H
#include <jinclude.h>
#define JPEG_INTERNALS
#include <jpeglib.h>
#include "jsamplecomp.h"
/* Fully reversible */
INLINE
LOCAL(void)
rgb_to_cmyk(_JSAMPLE r, _JSAMPLE g, _JSAMPLE b,
_JSAMPLE *c, _JSAMPLE *m, _JSAMPLE *y, _JSAMPLE *k)
{
double ctmp = 1.0 - ((double)r / (double)_MAXJSAMPLE);
double mtmp = 1.0 - ((double)g / (double)_MAXJSAMPLE);
double ytmp = 1.0 - ((double)b / (double)_MAXJSAMPLE);
double ktmp = MIN(MIN(ctmp, mtmp), ytmp);
if (ktmp == 1.0) ctmp = mtmp = ytmp = 0.0;
else {
ctmp = (ctmp - ktmp) / (1.0 - ktmp);
mtmp = (mtmp - ktmp) / (1.0 - ktmp);
ytmp = (ytmp - ktmp) / (1.0 - ktmp);
}
*c = (_JSAMPLE)((double)_MAXJSAMPLE - ctmp * (double)_MAXJSAMPLE + 0.5);
*m = (_JSAMPLE)((double)_MAXJSAMPLE - mtmp * (double)_MAXJSAMPLE + 0.5);
*y = (_JSAMPLE)((double)_MAXJSAMPLE - ytmp * (double)_MAXJSAMPLE + 0.5);
*k = (_JSAMPLE)((double)_MAXJSAMPLE - ktmp * (double)_MAXJSAMPLE + 0.5);
}
/* Fully reversible only for C/M/Y/K values generated with rgb_to_cmyk() */
INLINE
LOCAL(void)
cmyk_to_rgb(_JSAMPLE c, _JSAMPLE m, _JSAMPLE y, _JSAMPLE k,
_JSAMPLE *r, _JSAMPLE *g, _JSAMPLE *b)
{
*r = (_JSAMPLE)((double)c * (double)k / (double)_MAXJSAMPLE + 0.5);
*g = (_JSAMPLE)((double)m * (double)k / (double)_MAXJSAMPLE + 0.5);
*b = (_JSAMPLE)((double)y * (double)k / (double)_MAXJSAMPLE + 0.5);
}
#endif /* CMYK_H */

View File

@@ -1,619 +0,0 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.56])
AC_INIT([mozjpeg], [3.2])
BUILD=`date +%Y%m%d`
AM_INIT_AUTOMAKE([-Wall foreign dist-bzip2])
AC_PREFIX_DEFAULT(/opt/mozjpeg)
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
# Checks for programs.
SAVED_CFLAGS=${CFLAGS}
SAVED_CPPFLAGS=${CPPFLAGS}
AC_PROG_CPP
AC_PROG_CC
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
AM_PROG_AS
AM_PROG_CC_C_O
AC_PROG_INSTALL
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
AC_PROG_LIBTOOL
AC_PROG_LN_S
AC_ARG_WITH([build-date], [Use custom build string to enable reproducible builds (default: YYMMDD)],
[BUILD="$with_build_date"],
[BUILD=`date +%Y%m%d`])
PKG_PROG_PKG_CONFIG
# When the prefix is /opt/libjpeg-turbo, we assume that an "official" binary is
# being created, and thus we install things into specific locations.
old_prefix=${prefix}
if test "x$prefix" = "xNONE" -a "x$ac_default_prefix" != "x"; then
prefix=$ac_default_prefix
fi
DATADIR=`eval echo ${datadir}`
DATADIR=`eval echo $DATADIR`
if test "$DATADIR" = "/opt/libjpeg-turbo/share"; then
datadir='${prefix}'
fi
DATADIR=`eval echo ${datarootdir}`
DATADIR=`eval echo $DATADIR`
if test "$DATADIR" = "/opt/libjpeg-turbo/share"; then
datarootdir='${prefix}'
fi
DOCDIR=`eval echo ${docdir}`
DOCDIR=`eval echo $DOCDIR`
if test "$DOCDIR" = "/opt/libjpeg-turbo/doc/libjpeg-turbo"; then
docdir='${datadir}/doc'
fi
old_exec_prefix=${exec_prefix}
if test "x$exec_prefix" = "xNONE"; then
exec_prefix=${prefix}
fi
AC_CHECK_SIZEOF(size_t)
if test "x${libdir}" = 'x${exec_prefix}/lib' -o "x${libdir}" = 'x${prefix}/lib'; then
LIBDIR=`eval echo ${libdir}`
LIBDIR=`eval echo $LIBDIR`
if test "$LIBDIR" = "/opt/mozjpeg/lib"; then
case $host_os in
darwin*)
;;
*)
if test "${ac_cv_sizeof_size_t}" = "8"; then
libdir='${exec_prefix}/lib64'
elif test "${ac_cv_sizeof_size_t}" = "4"; then
libdir='${exec_prefix}/lib32'
fi
;;
esac
fi
fi
exec_prefix=${old_exec_prefix}
prefix=${old_prefix}
# Check whether compiler supports pointers to undefined structures
AC_MSG_CHECKING(whether compiler supports pointers to undefined structures)
AC_TRY_COMPILE([ typedef struct undefined_structure *undef_struct_ptr; ], ,
AC_MSG_RESULT(yes),
[AC_MSG_RESULT(no)
AC_DEFINE([INCOMPLETE_TYPES_BROKEN], [1],
[Compiler does not support pointers to undefined structures.])])
if test "x${GCC}" = "xyes"; then
if test "x${SAVED_CFLAGS}" = "x"; then
CFLAGS=-O3
fi
if test "x${SAVED_CPPFLAGS}" = "x"; then
CPPFLAGS=-Wall
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
fi
# Checks for libraries.
AC_CHECK_LIB([m],[pow])
PKG_CHECK_MODULES([libpng], [libpng], [HAVE_LIBPNG=1], [
PKG_CHECK_MODULES([libpng], [libpng12], [HAVE_LIBPNG=1], [HAVE_LIBPNG=0])
])
AM_CONDITIONAL([HAVE_LIBPNG], [test "$HAVE_LIBPNG" -eq 1])
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([stddef.h stdlib.h locale.h string.h])
AC_CHECK_HEADER([sys/types.h],
AC_DEFINE([NEED_SYS_TYPES_H], 1, [Define if you need to include <sys/types.h> to get size_t.]))
# 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 your (broken) compiler shifts signed values as if they were unsigned.])],
[AC_MSG_RESULT(yes)],
[AC_MSG_RESULT(Assuming that right shift is signed on target machine.)])
# Checks for library functions.
AC_CHECK_FUNCS([memset memcpy], [],
[AC_DEFINE([NEED_BSD_STRINGS], 1,
[Define if you have BSD-like bzero and bcopy in <strings.h> rather than memset/memcpy in <string.h>.])])
AC_MSG_CHECKING([libjpeg API version])
AC_ARG_VAR(JPEG_LIB_VERSION, [libjpeg API version (62, 70, or 80)])
if test "x$JPEG_LIB_VERSION" = "x"; then
AC_ARG_WITH([jpeg7],
AC_HELP_STRING([--with-jpeg7],
[Emulate libjpeg v7 API/ABI (this makes mozjpeg backward incompatible with libjpeg v6b.)]))
AC_ARG_WITH([jpeg8],
AC_HELP_STRING([--with-jpeg8],
[Emulate libjpeg v8 API/ABI (this makes mozjpeg backward incompatible with libjpeg v6b.)]))
if test "x${with_jpeg8}" = "xyes"; then
JPEG_LIB_VERSION=80
else
if test "x${with_jpeg7}" = "xyes"; then
JPEG_LIB_VERSION=70
else
JPEG_LIB_VERSION=62
fi
fi
fi
JPEG_LIB_VERSION_DECIMAL=`expr $JPEG_LIB_VERSION / 10`.`expr $JPEG_LIB_VERSION % 10`
AC_SUBST(JPEG_LIB_VERSION_DECIMAL)
AC_MSG_RESULT([$JPEG_LIB_VERSION_DECIMAL])
AC_DEFINE_UNQUOTED(JPEG_LIB_VERSION, [$JPEG_LIB_VERSION],
[libjpeg API version])
AC_ARG_VAR(SO_MAJOR_VERSION,
[Major version of the mozjpeg shared library (default is determined by the API version)])
AC_ARG_VAR(SO_MINOR_VERSION,
[Minor version of the mozjpeg shared library (default is determined by the API version)])
if test "x$SO_MAJOR_VERSION" = "x"; then
case "$JPEG_LIB_VERSION" in
62) SO_MAJOR_VERSION=$JPEG_LIB_VERSION ;;
*) SO_MAJOR_VERSION=`expr $JPEG_LIB_VERSION / 10` ;;
esac
fi
if test "x$SO_MINOR_VERSION" = "x"; then
case "$JPEG_LIB_VERSION" in
80) SO_MINOR_VERSION=2 ;;
*) SO_MINOR_VERSION=0 ;;
esac
fi
RPM_CONFIG_ARGS=
# Memory source/destination managers
SO_AGE=1
MEM_SRCDST_FUNCTIONS=
if test "x${with_jpeg8}" != "xyes"; then
AC_MSG_CHECKING([whether to include in-memory source/destination managers])
AC_ARG_WITH([mem-srcdst],
AC_HELP_STRING([--without-mem-srcdst],
[Do not include in-memory source/destination manager functions when emulating the libjpeg v6b or v7 API/ABI]))
if test "x$with_mem_srcdst" != "xno"; then
AC_MSG_RESULT(yes)
AC_DEFINE([MEM_SRCDST_SUPPORTED], [1],
[Support in-memory source/destination managers])
SO_AGE=2
MEM_SRCDST_FUNCTIONS="global: jpeg_mem_dest; jpeg_mem_src;";
else
AC_MSG_RESULT(no)
RPM_CONFIG_ARGS="$RPM_CONFIG_ARGS --without-mem-srcdst"
fi
fi
AC_MSG_CHECKING([libjpeg shared library version])
AC_MSG_RESULT([$SO_MAJOR_VERSION.$SO_AGE.$SO_MINOR_VERSION])
LIBTOOL_CURRENT=`expr $SO_MAJOR_VERSION + $SO_AGE`
AC_SUBST(LIBTOOL_CURRENT)
AC_SUBST(SO_MAJOR_VERSION)
AC_SUBST(SO_MINOR_VERSION)
AC_SUBST(SO_AGE)
AC_SUBST(MEM_SRCDST_FUNCTIONS)
AC_DEFINE_UNQUOTED(MOZJPEG_VERSION, [$VERSION], [mozjpeg version])
m4_define(version_triplet,m4_split(AC_PACKAGE_VERSION,[[.]]))
m4_define(version_major,m4_argn(1,version_triplet))
m4_define(version_minor,m4_argn(2,version_triplet))
m4_define(version_revision,m4_argn(3,version_triplet))
VERSION_MAJOR=version_major
VERSION_MINOR=version_minor
VERSION_REVISION=version_revision
LIBJPEG_TURBO_VERSION_NUMBER=`printf "%d%03d%03d" $VERSION_MAJOR $VERSION_MINOR $VERSION_REVISION`
AC_DEFINE_UNQUOTED(LIBJPEG_TURBO_VERSION_NUMBER, [$LIBJPEG_TURBO_VERSION_NUMBER], [libjpeg-turbo version in integer form])
VERSION_SCRIPT=yes
AC_ARG_ENABLE([ld-version-script],
AS_HELP_STRING([--disable-ld-version-script],
[Disable linker version script for mozjpeg (default is to use linker version script if the linker supports it)]),
[VERSION_SCRIPT=$enableval], [])
AC_MSG_CHECKING([whether the linker supports version scripts])
SAVED_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS -Wl,--version-script,conftest.map"
cat > conftest.map <<EOF
VERS_1 {
global: *;
};
EOF
AC_LINK_IFELSE([AC_LANG_SOURCE([AC_LANG_PROGRAM([], [])])],
[VERSION_SCRIPT_FLAG=-Wl,--version-script,;
AC_MSG_RESULT([yes (GNU style)])],
[])
if test "x$VERSION_SCRIPT_FLAG" = "x"; then
LDFLAGS="$SAVED_LDFLAGS -Wl,-M,conftest.map"
AC_LINK_IFELSE([AC_LANG_SOURCE([AC_LANG_PROGRAM([], [])])],
[VERSION_SCRIPT_FLAG=-Wl,-M,;
AC_MSG_RESULT([yes (Sun style)])],
[])
fi
if test "x$VERSION_SCRIPT_FLAG" = "x"; then
VERSION_SCRIPT=no
AC_MSG_RESULT(no)
fi
LDFLAGS="$SAVED_LDFLAGS"
AC_MSG_CHECKING([whether to use version script when building mozjpeg])
AC_MSG_RESULT($VERSION_SCRIPT)
AM_CONDITIONAL(VERSION_SCRIPT, test "x$VERSION_SCRIPT" = "xyes")
AC_SUBST(VERSION_SCRIPT_FLAG)
# Check for non-broken inline under various spellings
AC_MSG_CHECKING(for inline)
ljt_cv_inline=""
AC_TRY_COMPILE(, [} inline __attribute__((always_inline)) int foo() { return 0; }
int bar() { return foo();], ljt_cv_inline="inline __attribute__((always_inline))",
AC_TRY_COMPILE(, [} __inline__ int foo() { return 0; }
int bar() { return foo();], ljt_cv_inline="__inline__",
AC_TRY_COMPILE(, [} __inline int foo() { return 0; }
int bar() { return foo();], ljt_cv_inline="__inline",
AC_TRY_COMPILE(, [} inline int foo() { return 0; }
int bar() { return foo();], ljt_cv_inline="inline"))))
AC_MSG_RESULT($ljt_cv_inline)
AC_DEFINE_UNQUOTED([INLINE],[$ljt_cv_inline],[How to obtain function inlining.])
# Arithmetic coding support
AC_MSG_CHECKING([whether to include arithmetic encoding support])
AC_ARG_WITH([arith-enc],
AC_HELP_STRING([--without-arith-enc],
[Do not include arithmetic encoding support when emulating the libjpeg v6b API/ABI]))
if test "x$with_12bit" = "xyes"; then
with_arith_enc=no
fi
if test "x${with_jpeg8}" = "xyes" -o "x${with_jpeg7}" = "xyes"; then
with_arith_enc=yes
fi
if test "x$with_arith_enc" = "xno"; then
AC_MSG_RESULT(no)
RPM_CONFIG_ARGS="$RPM_CONFIG_ARGS --without-arith-enc"
else
AC_DEFINE([C_ARITH_CODING_SUPPORTED], [1], [Support arithmetic encoding])
AC_MSG_RESULT(yes)
fi
AM_CONDITIONAL([WITH_ARITH_ENC], [test "x$with_arith_enc" != "xno"])
AC_MSG_CHECKING([whether to include arithmetic decoding support])
AC_ARG_WITH([arith-dec],
AC_HELP_STRING([--without-arith-dec],
[Do not include arithmetic decoding support when emulating the libjpeg v6b API/ABI]))
if test "x$with_12bit" = "xyes"; then
with_arith_dec=no
fi
if test "x${with_jpeg8}" = "xyes" -o "x${with_jpeg7}" = "xyes"; then
with_arith_dec=yes
fi
if test "x$with_arith_dec" = "xno"; then
AC_MSG_RESULT(no)
RPM_CONFIG_ARGS="$RPM_CONFIG_ARGS --without-arith-dec"
else
AC_DEFINE([D_ARITH_CODING_SUPPORTED], [1], [Support arithmetic decoding])
AC_MSG_RESULT(yes)
fi
AM_CONDITIONAL([WITH_ARITH_DEC], [test "x$with_arith_dec" != "xno"])
AM_CONDITIONAL([WITH_ARITH],
[test "x$with_arith_dec" != "xno" -o "x$with_arith_enc" != "xno"])
# 12-bit component support
AC_MSG_CHECKING([whether to use 12-bit samples])
AC_ARG_WITH([12bit],
AC_HELP_STRING([--with-12bit], [Encode/decode JPEG images with 12-bit samples (implies --without-simd --without-turbojpeg --without-arith-dec --without-arith-enc)]))
if test "x$with_12bit" = "xyes"; then
AC_DEFINE([BITS_IN_JSAMPLE], [12], [use 8 or 12])
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
fi
AM_CONDITIONAL([WITH_12BIT], [test "x$with_12bit" = "xyes"])
# TurboJPEG support
AC_MSG_CHECKING([whether to build TurboJPEG C wrapper])
AC_ARG_WITH([turbojpeg],
AC_HELP_STRING([--without-turbojpeg],
[Do not include the TurboJPEG wrapper library and associated test programs]))
if test "x$with_12bit" = "xyes"; then
with_turbojpeg=no
fi
if test "x$with_turbojpeg" = "xno"; then
AC_MSG_RESULT(no)
RPM_CONFIG_ARGS="$RPM_CONFIG_ARGS --without-turbojpeg"
else
AC_MSG_RESULT(yes)
fi
# Java support
AC_ARG_VAR(JAVAC, [Java compiler command (default: javac)])
if test "x$JAVAC" = "x"; then
JAVAC=javac
fi
AC_SUBST(JAVAC)
AC_ARG_VAR(JAVACFLAGS, [Java compiler flags])
AC_SUBST(JAVACFLAGS)
AC_ARG_VAR(JAR, [Java archive command (default: jar)])
if test "x$JAR" = "x"; then
JAR=jar
fi
AC_SUBST(JAR)
AC_ARG_VAR(JAVA, [Java runtime command (default: java)])
if test "x$JAVA" = "x"; then
JAVA=java
fi
AC_SUBST(JAVA)
AC_ARG_VAR(JNI_CFLAGS,
[C compiler flags needed to include jni.h (default: -I/System/Library/Frameworks/JavaVM.framework/Headers on OS X, '-I/usr/java/include -I/usr/java/include/solaris' on Solaris, and '-I/usr/java/default/include -I/usr/java/default/include/linux' on Linux)])
AC_MSG_CHECKING([whether to build TurboJPEG Java wrapper])
AC_ARG_WITH([java],
AC_HELP_STRING([--with-java], [Build Java wrapper for the TurboJPEG library]))
if test "x$with_12bit" = "xyes" -o "x$with_turbojpeg" = "xno"; then
with_java=no
fi
WITH_JAVA=0
if test "x$with_java" = "xyes"; then
AC_MSG_RESULT(yes)
case $host_os in
darwin*)
DEFAULT_JNI_CFLAGS=-I/System/Library/Frameworks/JavaVM.framework/Headers
;;
solaris*)
DEFAULT_JNI_CFLAGS='-I/usr/java/include -I/usr/java/include/solaris'
;;
linux*)
DEFAULT_JNI_CFLAGS='-I/usr/java/default/include -I/usr/java/default/include/linux'
;;
esac
if test "x$JNI_CFLAGS" = "x"; then
JNI_CFLAGS=$DEFAULT_JNI_CFLAGS
fi
SAVE_CPPFLAGS=${CPPFLAGS}
CPPFLAGS="${CPPFLAGS} ${JNI_CFLAGS}"
AC_CHECK_HEADERS([jni.h], [DUMMY=1],
[AC_MSG_ERROR([Could not find JNI header file])])
CPPFLAGS=${SAVE_CPPFLAGS}
AC_SUBST(JNI_CFLAGS)
RPM_CONFIG_ARGS="$RPM_CONFIG_ARGS --with-java"
JAVA_RPM_CONTENTS_1='%dir %{_datadir}/classes'
JAVA_RPM_CONTENTS_2=%{_datadir}/classes/turbojpeg.jar
WITH_JAVA=1
else
AC_MSG_RESULT(no)
fi
AM_CONDITIONAL([WITH_JAVA], [test "x$with_java" = "xyes"])
AC_SUBST(WITH_JAVA)
AC_SUBST(JAVA_RPM_CONTENTS_1)
AC_SUBST(JAVA_RPM_CONTENTS_2)
# optionally force using gas-preprocessor.pl for compatibility testing
AC_ARG_WITH([gas-preprocessor],
AC_HELP_STRING([--with-gas-preprocessor],
[Force using gas-preprocessor.pl on ARM.]))
if test "x${with_gas_preprocessor}" = "xyes"; then
case $host_os in
darwin*)
CCAS="gas-preprocessor.pl -fix-unreq $CC"
;;
*)
CCAS="gas-preprocessor.pl -no-fix-unreq $CC"
;;
esac
AC_SUBST([CCAS])
fi
# SIMD is optional
AC_ARG_WITH([simd],
AC_HELP_STRING([--without-simd], [Do not include SIMD extensions]))
if test "x$with_12bit" = "xyes"; then
with_simd=no
fi
if test "x${with_simd}" != "xno"; then
require_simd=no
if test "x${with_simd}" = "xyes"; then
require_simd=yes
fi
# Check if we're on a supported CPU
AC_MSG_CHECKING([if we have SIMD optimisations for cpu type])
case "$host_cpu" in
x86_64 | amd64)
AC_MSG_RESULT([yes (x86_64)])
AC_PROG_NASM
simd_arch=x86_64
;;
i*86 | x86 | ia32)
AC_MSG_RESULT([yes (i386)])
AC_PROG_NASM
simd_arch=i386
;;
arm*)
AC_MSG_RESULT([yes (arm)])
AC_MSG_CHECKING([if the assembler is GNU-compatible and can be used])
AC_CHECK_COMPATIBLE_ARM_ASSEMBLER_IFELSE(
[if test "x$ac_use_gas_preprocessor" = "xyes"; then
AC_MSG_RESULT([yes (with gas-preprocessor)])
else
AC_MSG_RESULT([yes])
fi
simd_arch=arm],
[AC_MSG_RESULT([no])
with_simd=no])
if test "x${with_simd}" = "xno"; then
if test "x${require_simd}" = "xyes"; then
AC_MSG_ERROR([SIMD support can't be enabled.])
else
AC_MSG_WARN([SIMD support can't be enabled. Performance will suffer.])
fi
fi
;;
aarch64*)
AC_MSG_RESULT([yes (arm64)])
AC_MSG_CHECKING([if the assembler is GNU-compatible and can be used])
AC_CHECK_COMPATIBLE_ARM64_ASSEMBLER_IFELSE(
[if test "x$ac_use_gas_preprocessor" = "xyes"; then
AC_MSG_RESULT([yes (with gas-preprocessor)])
else
AC_MSG_RESULT([yes])
fi
simd_arch=aarch64],
[AC_MSG_RESULT([no])
with_simd=no])
if test "x${with_simd}" = "xno"; then
if test "x${require_simd}" = "xyes"; then
AC_MSG_ERROR([SIMD support can't be enabled.])
else
AC_MSG_WARN([SIMD support can't be enabled. Performance will suffer.])
fi
fi
;;
mips*)
AC_MSG_RESULT([yes (mips)])
AC_MSG_CHECKING([if the assembler is GNU-compatible and can be used])
AC_CHECK_COMPATIBLE_MIPS_ASSEMBLER_IFELSE(
[AC_MSG_RESULT([yes])
simd_arch=mips],
[AC_MSG_RESULT([no])
with_simd=no])
if test "x${with_simd}" = "xno"; then
if test "x${require_simd}" = "xyes"; then
AC_MSG_ERROR([SIMD support can't be enabled.])
else
AC_MSG_WARN([SIMD support can't be enabled. Performance will suffer.])
fi
fi
;;
powerpc*)
AC_MSG_RESULT([yes (powerpc)])
simd_arch=powerpc
;;
*)
AC_MSG_RESULT([no ("$host_cpu")])
with_simd=no;
if test "x${require_simd}" = "xyes"; then
AC_MSG_ERROR([SIMD support not available for this CPU.])
else
AC_MSG_WARN([SIMD support not available for this CPU. Performance will suffer.])
fi
;;
esac
if test "x${with_simd}" != "xno"; then
AC_DEFINE([WITH_SIMD], [1], [Use accelerated SIMD routines.])
fi
else
RPM_CONFIG_ARGS="$RPM_CONFIG_ARGS --without-simd"
fi
AM_CONDITIONAL([WITH_SIMD], [test "x$with_simd" != "xno"])
AM_CONDITIONAL([WITH_SSE_FLOAT_DCT], [test "x$simd_arch" = "xx86_64" -o "x$simd_arch" = "xi386"])
AM_CONDITIONAL([SIMD_I386], [test "x$simd_arch" = "xi386"])
AM_CONDITIONAL([SIMD_X86_64], [test "x$simd_arch" = "xx86_64"])
AM_CONDITIONAL([SIMD_ARM], [test "x$simd_arch" = "xarm"])
AM_CONDITIONAL([SIMD_ARM_64], [test "x$simd_arch" = "xaarch64"])
AM_CONDITIONAL([SIMD_MIPS], [test "x$simd_arch" = "xmips"])
AM_CONDITIONAL([SIMD_POWERPC], [test "x$simd_arch" = "xpowerpc"])
AM_CONDITIONAL([X86_64], [test "x$host_cpu" = "xx86_64" -o "x$host_cpu" = "xamd64"])
AM_CONDITIONAL([WITH_TURBOJPEG], [test "x$with_turbojpeg" != "xno"])
AM_CONDITIONAL([CROSS_COMPILING], [test "x$cross_compiling" = "xyes"])
AC_ARG_VAR(PKGNAME, [distribution package name (default: mozjpeg)])
if test "x$PKGNAME" = "x"; then
PKGNAME=$PACKAGE_NAME
fi
AC_SUBST(PKGNAME)
case "$host_cpu" in
x86_64)
RPMARCH=x86_64
DEBARCH=amd64
;;
i*86 | x86 | ia32)
RPMARCH=i386
DEBARCH=i386
;;
*)
RPMARCH=`uname -m`
DEBARCH=$RPMARCH
;;
esac
if test "${docdir}" = ""; then
docdir=${datadir}/doc
AC_SUBST(docdir)
fi
AC_SUBST(RPMARCH)
AC_SUBST(RPM_CONFIG_ARGS)
AC_SUBST(DEBARCH)
AC_SUBST(BUILD)
AC_DEFINE_UNQUOTED([BUILD], "$BUILD", [libjpeg-turbo build number])
# NOTE: autoheader automatically modifies the input file of the first
# invocation of AC_CONFIG_HEADERS, so we put config.h first to prevent
# jconfig.h.in from being clobbered. config.h is used only internally, whereas
# jconfig.h contains macros that are relevant to external programs (macros that
# specify which features were built into the library.)
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_HEADERS([jconfig.h])
AC_CONFIG_HEADERS([jconfigint.h])
AC_CONFIG_FILES([pkgscripts/mozjpeg.spec.tmpl:release/mozjpeg.spec.in])
AC_CONFIG_FILES([pkgscripts/makecygwinpkg.tmpl:release/makecygwinpkg.in])
AC_CONFIG_FILES([pkgscripts/makedpkg.tmpl:release/makedpkg.in])
AC_CONFIG_FILES([pkgscripts/makemacpkg.tmpl:release/makemacpkg.in])
AC_CONFIG_FILES([pkgscripts/uninstall.tmpl:release/uninstall.in])
AC_CONFIG_FILES([pkgscripts/libjpeg.pc:release/libjpeg.pc.in])
AC_CONFIG_FILES([pkgscripts/libturbojpeg.pc:release/libturbojpeg.pc.in])
if test "x$with_turbojpeg" != "xno"; then
AC_CONFIG_FILES([tjbenchtest])
fi
if test "x$with_java" = "xyes"; then
AC_CONFIG_FILES([tjbenchtest.java])
AC_CONFIG_FILES([tjexampletest])
fi
AC_CONFIG_FILES([libjpeg.map])
AC_CONFIG_FILES([Makefile simd/Makefile])
AC_CONFIG_FILES([java/Makefile])
AC_CONFIG_FILES([md5/Makefile])
AC_OUTPUT

95
croptest.in Executable file
View File

@@ -0,0 +1,95 @@
#!/bin/bash
set -u
set -e
trap onexit INT
trap onexit TERM
trap onexit EXIT
onexit()
{
if [ -d $OUTDIR ]; then
rm -rf $OUTDIR
fi
}
runme()
{
echo \*\*\* $*
$*
}
IMAGE=vgl_6548_0026a.bmp
WIDTH=128
HEIGHT=95
IMGDIR=@CMAKE_CURRENT_SOURCE_DIR@/testimages
OUTDIR=`mktemp -d /tmp/__croptest_output.XXXXXX`
EXEDIR=@CMAKE_CURRENT_BINARY_DIR@
if [ -d $OUTDIR ]; then
rm -rf $OUTDIR
fi
mkdir -p $OUTDIR
exec >$EXEDIR/croptest.log
echo "============================================================"
echo "$IMAGE ($WIDTH x $HEIGHT)"
echo "============================================================"
echo
for PROGARG in "" -progressive; do
cp $IMGDIR/$IMAGE $OUTDIR
basename=`basename $IMAGE .bmp`
echo "------------------------------------------------------------"
echo "Generating test images"
echo "------------------------------------------------------------"
echo
runme $EXEDIR/cjpeg $PROGARG -grayscale -outfile $OUTDIR/${basename}_GRAY.jpg $IMGDIR/${basename}.bmp
runme $EXEDIR/cjpeg $PROGARG -sample 2x2 -outfile $OUTDIR/${basename}_420.jpg $IMGDIR/${basename}.bmp
runme $EXEDIR/cjpeg $PROGARG -sample 2x1 -outfile $OUTDIR/${basename}_422.jpg $IMGDIR/${basename}.bmp
runme $EXEDIR/cjpeg $PROGARG -sample 1x2 -outfile $OUTDIR/${basename}_440.jpg $IMGDIR/${basename}.bmp
runme $EXEDIR/cjpeg $PROGARG -sample 1x1 -outfile $OUTDIR/${basename}_444.jpg $IMGDIR/${basename}.bmp
echo
for NSARG in "" -nosmooth; do
for COLORSARG in "" "-colors 256 -dither none -onepass"; do
for Y in {0..16}; do
for H in {1..16}; do
X=$(( (Y*16)%128 ))
W=$(( WIDTH-X-7 ))
if [ $Y -le 15 ]; then
CROPSPEC="${W}x${H}+${X}+${Y}"
else
Y2=$(( HEIGHT-H ));
CROPSPEC="${W}x${H}+${X}+${Y2}"
fi
echo "------------------------------------------------------------"
echo $PROGARG $NSARG $COLORSARG -crop $CROPSPEC
echo "------------------------------------------------------------"
echo
for samp in GRAY 420 422 440 444; do
$EXEDIR/djpeg $NSARG $COLORSARG -rgb -outfile $OUTDIR/${basename}_${samp}_full.ppm $OUTDIR/${basename}_${samp}.jpg
convert -crop $CROPSPEC $OUTDIR/${basename}_${samp}_full.ppm $OUTDIR/${basename}_${samp}_ref.ppm
runme $EXEDIR/djpeg $NSARG $COLORSARG -crop $CROPSPEC -rgb -outfile $OUTDIR/${basename}_${samp}.ppm $OUTDIR/${basename}_${samp}.jpg
runme cmp $OUTDIR/${basename}_${samp}.ppm $OUTDIR/${basename}_${samp}_ref.ppm
done
echo
done
done
done
done
done
echo SUCCESS!

233
djpeg.1
View File

@@ -1,4 +1,4 @@
.TH DJPEG 1 "18 February 2016"
.TH DJPEG 1 "17 June 2024"
.SH NAME
djpeg \- decompress a JPEG file to an image file
.SH SYNOPSIS
@@ -15,8 +15,7 @@ djpeg \- decompress a JPEG file to an image file
.B djpeg
decompresses the named JPEG file, or the standard input if no file is named,
and produces an image file on the standard output. PBMPLUS (PPM/PGM), BMP,
GIF, Targa, or RLE (Utah Raster Toolkit) output format can be selected.
(RLE is supported only if the URT library is available.)
GIF, or Targa output format can be selected.
.SH OPTIONS
All switch names may be abbreviated; for example,
.B \-grayscale
@@ -29,47 +28,46 @@ Upper and lower case are equivalent (thus
.B \-BMP
is the same as
.BR \-bmp ).
British spellings are also accepted (e.g.,
British spellings are also accepted (e.g.
.BR \-greyscale ),
though for brevity these are not mentioned below.
.PP
The basic switches are:
.TP
.BI \-colors " N"
Reduce image to at most N colors. This reduces the number of colors used in
the output image, so that it can be displayed on a colormapped display or
stored in a colormapped file format. For example, if you have an 8-bit
display, you'd need to reduce to 256 or fewer colors.
Reduce image to at most N colors [legacy feature]. This reduces the number of
colors used in the output image so that it can be stored in a colormapped file
format. This feature cannot be used when decompressing lossless JPEG images.
.TP
.BI \-quantize " N"
Same as
.BR \-colors .
.B \-colors
is the recommended name,
is the recommended name.
.B \-quantize
is provided only for backwards compatibility.
is provided only for backward compatibility.
.TP
.B \-fast
Select recommended processing options for fast, low quality output. (The
default options are chosen for highest quality output.) Currently, this is
equivalent to \fB\-dct fast \-nosmooth \-onepass \-dither ordered\fR.
Select recommended processing options for low-quality output [legacy feature].
(The default options are chosen for highest-quality output.) Currently, this
is equivalent to \fB\-dct fast \-nosmooth \-onepass \-dither ordered\fR. On
modern CPUs, these settings have little or no performance benefit and are
retained solely for backward compatibility.
.TP
.B \-grayscale
Force grayscale output even if JPEG file is color. Useful for viewing on
monochrome displays; also,
.B djpeg
runs noticeably faster in this mode.
Force grayscale output even if JPEG file is full-color. This feature cannot be
used when decompressing full-color lossless JPEG images.
.TP
.B \-rgb
Force RGB output even if JPEG file is grayscale.
Force RGB output even if JPEG file is grayscale. This feature cannot be used
when decompressing grayscale lossless JPEG images.
.TP
.BI \-scale " M/N"
Scale the output image by a factor M/N. Currently the scale factor must be
M/8, where M is an integer between 1 and 16 inclusive, or any reduced fraction
thereof (such as 1/2, 3/4, etc.) Scaling is handy if the image is larger than
your screen; also,
.B djpeg
runs much faster when scaling down the output.
your screen. This feature cannot be used when decompressing lossless JPEG
images.
.TP
.B \-bmp
Select BMP output format (Windows flavor). 8-bit colormapped format is
@@ -78,21 +76,36 @@ emitted if
or
.B \-grayscale
is specified, or if the JPEG file is grayscale; otherwise, 24-bit full-color
format is emitted.
format is emitted. This format can only be used when decompressing
8-bit-per-sample JPEG images.
.TP
.B \-gif
Select GIF output format. Since GIF does not support more than 256 colors,
Select GIF output format (LZW-compressed) [legacy feature]. Since GIF does not
support more than 256 colors,
.B \-colors 256
is assumed (unless you specify a smaller number of colors).
is assumed (unless you specify a smaller number of colors). If you specify
.BR \-fast,
the default number of colors is 216. This format can only be used when
decompressing 8-bit-per-sample or 12-bit-per-sample lossy JPEG images.
.TP
.B \-gif0
Select GIF output format (uncompressed) [legacy feature]. Since GIF does not
support more than 256 colors,
.B \-colors 256
is assumed (unless you specify a smaller number of colors). If you specify
.BR \-fast,
the default number of colors is 216. This format can only be used when
decompressing 8-bit-per-sample or 12-bit-per-sample lossy JPEG images.
.TP
.B \-os2
Select BMP output format (OS/2 1.x flavor). 8-bit colormapped format is
emitted if
Select BMP output format (OS/2 1.x flavor) [legacy feature]. 8-bit colormapped
format is emitted if
.B \-colors
or
.B \-grayscale
is specified, or if the JPEG file is grayscale; otherwise, 24-bit full-color
format is emitted.
format is emitted. This format can only be used when decompressing
8-bit-per-sample JPEG images.
.TP
.B \-pnm
Select PBMPLUS (PPM/PGM) output format (this is the default format).
@@ -100,67 +113,76 @@ PGM is emitted if the JPEG file is grayscale or if
.B \-grayscale
is specified; otherwise PPM is emitted.
.TP
.B \-rle
Select RLE output format. (Requires URT library.)
.TP
.B \-targa
Select Targa output format. Grayscale format is emitted if the JPEG file is
grayscale or if
Select Targa output format [legacy feature]. Grayscale format is emitted if
the JPEG file is grayscale or if
.B \-grayscale
is specified; otherwise, colormapped format is emitted if
.B \-colors
is specified; otherwise, 24-bit full-color format is emitted.
is specified; otherwise, 24-bit full-color format is emitted. This format can
only be used when decompressing 8-bit-per-sample JPEG images.
.PP
Switches for advanced users:
.TP
.B \-dct int
Use integer DCT method (default).
Use accurate integer DCT method (default).
.TP
.B \-dct fast
Use fast integer DCT (less accurate).
In libjpeg-turbo, the fast method is generally about 5-15% faster than the int
method when using the x86/x86-64 SIMD extensions (results may vary with other
SIMD implementations, or when using libjpeg-turbo without SIMD extensions.) If
the JPEG image was compressed using a quality level of 85 or below, then there
should be little or no perceptible difference between the two algorithms. When
decompressing images that were compressed using quality levels above 85,
however, the difference between the fast and int methods becomes more
pronounced. With images compressed using quality=97, for instance, the fast
method incurs generally about a 4-6 dB loss (in PSNR) relative to the int
method, but this can be larger for some images. If you can avoid it, do not
use the fast method when decompressing images that were compressed using
quality levels above 97. The algorithm often degenerates for such images and
can actually produce a more lossy output image than if the JPEG image had been
compressed using lower quality levels.
Use less accurate integer DCT method [legacy feature].
When the Independent JPEG Group's software was first released in 1991, the
decompression time for a 1-megapixel JPEG image on a mainstream PC was measured
in minutes. Thus, the \fBfast\fR integer DCT algorithm provided noticeable
performance benefits. On modern CPUs running libjpeg-turbo, however, the
decompression time for a 1-megapixel JPEG image is measured in milliseconds,
and thus the performance benefits of the \fBfast\fR algorithm are much less
noticeable. On modern x86/x86-64 CPUs that support AVX2 instructions, the
\fBfast\fR and \fBint\fR methods have similar performance. On other types of
CPUs, the \fBfast\fR method is generally about 5-15% faster than the \fBint\fR
method.
If the JPEG image was compressed using a quality level of 85 or below, then
there should be little or no perceptible quality difference between the two
algorithms. When decompressing images that were compressed using quality
levels above 85, however, the difference between the \fBfast\fR and \fBint\fR
methods becomes more pronounced. With images compressed using quality=97, for
instance, the \fBfast\fR method incurs generally about a 4-6 dB loss in PSNR
relative to the \fBint\fR method, but this can be larger for some images. If
you can avoid it, do not use the \fBfast\fR method when decompressing images
that were compressed using quality levels above 97. The algorithm often
degenerates for such images and can actually produce a more lossy output image
than if the JPEG image had been compressed using lower quality levels.
.TP
.B \-dct float
Use floating-point DCT method.
The float method is mainly a legacy feature. It does not produce significantly
more accurate results than the int method, and it is much slower. The float
method may also give different results on different machines due to varying
roundoff behavior, whereas the integer methods should give the same results on
all machines.
Use floating-point DCT method [legacy feature].
The \fBfloat\fR method does not produce significantly more accurate results
than the \fBint\fR method, and it is much slower. The \fBfloat\fR method may
also give different results on different machines due to varying roundoff
behavior, whereas the integer methods should give the same results on all
machines.
.TP
.B \-dither fs
Use Floyd-Steinberg dithering in color quantization.
Use Floyd-Steinberg dithering when quantizing colors [legacy feature].
.TP
.B \-dither ordered
Use ordered dithering in color quantization.
Use ordered dithering when quantizing colors [legacy feature].
.TP
.B \-dither none
Do not use dithering in color quantization.
By default, Floyd-Steinberg dithering is applied when quantizing colors; this
is slow but usually produces the best results. Ordered dither is a compromise
between speed and quality; no dithering is fast but usually looks awful. Note
that these switches have no effect unless color quantization is being done.
Ordered dither is only available in
Do not use dithering when quantizing colors [legacy feature]. By default,
Floyd-Steinberg dithering is applied when quantizing colors. This is slower
but usually produces the best results. Ordered dithering is a compromise
between speed and quality. No dithering is faster but usually looks awful.
Note that these switches have no effect unless color quantization is being
done. Ordered dithering is only available in
.B \-onepass
mode.
.TP
.BI \-icc " file"
Extract ICC color management profile to the specified file.
.TP
.BI \-map " file"
Quantize to the colors used in the specified image file. This is useful for
producing multiple files with identical color maps, or for forcing a
predefined set of colors to be used. The
Quantize to the colors used in the specified image file [legacy feature]. This
is useful for producing multiple files with identical color maps, or for
forcing a predefined set of colors to be used. The
.I file
must be a GIF or PPM file. This option overrides
.B \-colors
@@ -171,21 +193,34 @@ and
Use a faster, lower-quality upsampling routine.
.TP
.B \-onepass
Use one-pass instead of two-pass color quantization. The one-pass method is
faster and needs less memory, but it produces a lower-quality image.
Use one-pass instead of two-pass color quantization [legacy feature]. The
one-pass method needs less memory, but it produces a lower-quality image.
.B \-onepass
is ignored unless you also say
is ignored unless you also specify
.B \-colors
.IR N .
Also, the one-pass method is always used for grayscale output (the two-pass
method is no improvement then).
Also, the one-pass method is always used for grayscale output. (The two-pass
method has no improvement in that case.)
.TP
.BI \-maxmemory " N"
Set limit for amount of memory to use in processing large images. Value is
in thousands of bytes, or millions of bytes if "M" is attached to the
number. For example,
.B \-max 4m
selects 4000000 bytes. If more space is needed, temporary files will be used.
selects 4000000 bytes. If more space is needed, an error will occur.
.TP
.BI \-maxscans " N"
Abort if the JPEG image contains more than
.I N
scans. This feature demonstrates a method by which applications can guard
against denial-of-service attacks instigated by specially-crafted malformed
JPEG images containing numerous scans with missing image data or image data
consisting only of "EOB runs" (a feature of progressive JPEG images that allows
potentially hundreds of thousands of adjoining zero-value pixels to be
represented using only a few bytes.) Attempting to decompress such malformed
JPEG images can cause excessive CPU activity, since the decompressor must fully
process each scan (even if the scan is corrupt) before it can proceed to the
next scan.
.TP
.BI \-outfile " name"
Send output image to the named file, not to standard output.
@@ -194,6 +229,9 @@ Send output image to the named file, not to standard output.
Load input file into memory before decompressing. This feature was implemented
mainly as a way of testing the in-memory source manager (jpeg_mem_src().)
.TP
.BI \-report
Report decompression progress.
.TP
.BI \-skip " Y0,Y1"
Decompress all rows of the JPEG image except those between Y0 and Y1
(inclusive.) Note that if decompression scaling is being used, then Y0 and Y1
@@ -204,7 +242,14 @@ Decompress only a rectangular subregion of the image, starting at point X,Y
with width W and height H. If necessary, X will be shifted left to the nearest
iMCU boundary, and the width will be increased accordingly. Note that if
decompression scaling is being used, then X, Y, W, and H are relative to the
scaled image dimensions.
scaled image dimensions. Currently this option only works with the
PBMPLUS (PPM/PGM), GIF, and Targa output formats.
.TP
.BI \-strict
Treat all warnings as fatal. This feature also demonstrates a method by which
applications can guard against attacks instigated by specially-crafted
malformed JPEG images. Enabling this option will cause the decompressor to
abort if the JPEG image contains incomplete or corrupt image data.
.TP
.B \-verbose
Enable debug printout. More
@@ -219,42 +264,13 @@ Same as
Print version information and exit.
.SH EXAMPLES
.LP
This example decompresses the JPEG file foo.jpg, quantizes it to
256 colors, and saves the output in 8-bit BMP format in foo.bmp:
This example decompresses the JPEG file foo.jpg and saves the output in 8-bit
BMP format in foo.bmp:
.IP
.B djpeg \-colors 256 \-bmp
.B djpeg \-bmp
.I foo.jpg
.B >
.I foo.bmp
.SH HINTS
To get a quick preview of an image, use the
.B \-grayscale
and/or
.B \-scale
switches.
.B \-grayscale \-scale 1/8
is the fastest case.
.PP
Several options are available that trade off image quality to gain speed.
.B \-fast
turns on the recommended settings.
.PP
.B \-dct fast
and/or
.B \-nosmooth
gain speed at a small sacrifice in quality.
When producing a color-quantized image,
.B \-onepass \-dither ordered
is fast but much lower quality than the default behavior.
.B \-dither none
may give acceptable results in two-pass mode, but is seldom tolerable in
one-pass mode.
.PP
If you are fortunate enough to have very fast floating point hardware,
\fB\-dct float\fR may be even faster than \fB\-dct fast\fR. But on most
machines \fB\-dct float\fR is slower than \fB\-dct int\fR; in this case it is
not worth using, because its theoretical accuracy advantage is too small to be
significant in practice.
.SH ENVIRONMENT
.TP
.B JPEGMEM
@@ -283,10 +299,3 @@ Independent JPEG Group
This file was modified by The libjpeg-turbo Project to include only information
relevant to libjpeg-turbo, to wordsmith certain sections, and to describe
features not present in libjpeg.
.SH ISSUES
Support for compressed GIF output files was removed in djpeg v6b due to
concerns over the Unisys LZW patent. Although this patent expired in 2006,
djpeg still lacks compressed GIF support, for these historical reasons.
(Conversion of JPEG files to GIF is usually a bad idea anyway, since GIF is a
256-color format.) The uncompressed GIF files that djpeg generates are larger
than they should be, but they are readable by standard GIF decoders.

452
djpeg.c
View File

@@ -3,9 +3,9 @@
*
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2013 by Guido Vollbeding.
* Modified 2013-2019 by Guido Vollbeding.
* libjpeg-turbo Modifications:
* Copyright (C) 2010-2011, 2013-2016, D. R. Commander.
* Copyright (C) 2010-2011, 2013-2017, 2019-2020, 2022-2024, D. R. Commander.
* Copyright (C) 2015, Google, Inc.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
@@ -28,27 +28,20 @@
* works regardless of which command line style is used.
*/
#ifdef _MSC_VER
#define _CRT_SECURE_NO_DEPRECATE
#endif
#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
#include "jversion.h" /* for version message */
#include "jconfigint.h"
#include "wrppm.h"
#include <ctype.h> /* to declare isprint() */
#ifdef USE_CCOMMAND /* command-line reader for Macintosh */
#ifdef __MWERKS__
#include <SIOUX.h> /* Metrowerks needs this */
#include <console.h> /* ... and this */
#endif
#ifdef THINK_C
#include <console.h> /* Think declares it here */
#endif
#endif
/* Create the add-on message string table. */
#define JMESSAGE(code,string) string ,
#define JMESSAGE(code, string) string,
static const char * const cdjpeg_message_table[] = {
#include "cderror.h"
@@ -64,13 +57,13 @@ static const char * const cdjpeg_message_table[] = {
*/
typedef enum {
FMT_BMP, /* BMP format (Windows flavor) */
FMT_GIF, /* GIF format */
FMT_OS2, /* BMP format (OS/2 flavor) */
FMT_PPM, /* PPM/PGM (PBMPLUS formats) */
FMT_RLE, /* RLE format */
FMT_TARGA, /* Targa format */
FMT_TIFF /* TIFF format */
FMT_BMP, /* BMP format (Windows flavor) */
FMT_GIF, /* GIF format (LZW-compressed) */
FMT_GIF0, /* GIF format (uncompressed) */
FMT_OS2, /* BMP format (OS/2 flavor) */
FMT_PPM, /* PPM/PGM (PBMPLUS formats) */
FMT_TARGA, /* Targa format */
FMT_TIFF /* TIFF format */
} IMAGE_FORMATS;
#ifndef DEFAULT_FMT /* so can override from CFLAGS in Makefile */
@@ -90,16 +83,20 @@ static IMAGE_FORMATS requested_fmt;
static const char *progname; /* program name for error messages */
static char *icc_filename; /* for -icc switch */
static JDIMENSION max_scans; /* for -maxscans switch */
static char *outfilename; /* for -outfile switch */
boolean memsrc; /* for -memsrc switch */
boolean skip, crop;
JDIMENSION skip_start, skip_end;
JDIMENSION crop_x, crop_y, crop_width, crop_height;
static boolean memsrc; /* for -memsrc switch */
static boolean report; /* for -report switch */
static boolean skip, crop;
static JDIMENSION skip_start, skip_end;
static JDIMENSION crop_x, crop_y, crop_width, crop_height;
static boolean strict; /* for -strict switch */
#define INPUT_BUF_SIZE 4096
LOCAL(void)
usage (void)
usage(void)
/* complain about bad command line */
{
fprintf(stderr, "usage: %s [switches] ", progname);
@@ -110,8 +107,8 @@ usage (void)
#endif
fprintf(stderr, "Switches (names may be abbreviated):\n");
fprintf(stderr, " -colors N Reduce image to no more than N colors\n");
fprintf(stderr, " -fast Fast, low-quality processing\n");
fprintf(stderr, " -colors N Reduce image to no more than N colors [legacy feature]\n");
fprintf(stderr, " -fast Low-quality processing [legacy feature]\n");
fprintf(stderr, " -grayscale Force grayscale output\n");
fprintf(stderr, " -rgb Force RGB output\n");
fprintf(stderr, " -rgb565 Force RGB565 output\n");
@@ -123,56 +120,58 @@ usage (void)
(DEFAULT_FMT == FMT_BMP ? " (default)" : ""));
#endif
#ifdef GIF_SUPPORTED
fprintf(stderr, " -gif Select GIF output format%s\n",
fprintf(stderr, " -gif Select GIF output format (LZW-compressed)%s [legacy feature]\n",
(DEFAULT_FMT == FMT_GIF ? " (default)" : ""));
fprintf(stderr, " -gif0 Select GIF output format (uncompressed)%s [legacy feature]\n",
(DEFAULT_FMT == FMT_GIF0 ? " (default)" : ""));
#endif
#ifdef BMP_SUPPORTED
fprintf(stderr, " -os2 Select BMP output format (OS/2 style)%s\n",
fprintf(stderr, " -os2 Select BMP output format (OS/2 style)%s [legacy feature]\n",
(DEFAULT_FMT == FMT_OS2 ? " (default)" : ""));
#endif
#ifdef PPM_SUPPORTED
fprintf(stderr, " -pnm Select PBMPLUS (PPM/PGM) output format%s\n",
(DEFAULT_FMT == FMT_PPM ? " (default)" : ""));
#endif
#ifdef RLE_SUPPORTED
fprintf(stderr, " -rle Select Utah RLE output format%s\n",
(DEFAULT_FMT == FMT_RLE ? " (default)" : ""));
#endif
#ifdef TARGA_SUPPORTED
fprintf(stderr, " -targa Select Targa output format%s\n",
fprintf(stderr, " -targa Select Targa output format%s [legacy feature]\n",
(DEFAULT_FMT == FMT_TARGA ? " (default)" : ""));
#endif
fprintf(stderr, "Switches for advanced users:\n");
#ifdef DCT_ISLOW_SUPPORTED
fprintf(stderr, " -dct int Use integer DCT method%s\n",
fprintf(stderr, " -dct int Use accurate integer DCT method%s\n",
(JDCT_DEFAULT == JDCT_ISLOW ? " (default)" : ""));
#endif
#ifdef DCT_IFAST_SUPPORTED
fprintf(stderr, " -dct fast Use fast integer DCT (less accurate)%s\n",
fprintf(stderr, " -dct fast Use less accurate integer DCT method [legacy feature]%s\n",
(JDCT_DEFAULT == JDCT_IFAST ? " (default)" : ""));
#endif
#ifdef DCT_FLOAT_SUPPORTED
fprintf(stderr, " -dct float Use floating-point DCT method%s\n",
fprintf(stderr, " -dct float Use floating-point DCT method [legacy feature]%s\n",
(JDCT_DEFAULT == JDCT_FLOAT ? " (default)" : ""));
#endif
fprintf(stderr, " -dither fs Use F-S dithering (default)\n");
fprintf(stderr, " -dither none Don't use dithering in quantization\n");
fprintf(stderr, " -dither ordered Use ordered dither (medium speed, quality)\n");
fprintf(stderr, " -dither fs Use Floyd-Steinberg dithering when quantizing colors (default)\n");
fprintf(stderr, " [legacy feature]\n");
fprintf(stderr, " -dither none Don't use dithering when quantizing colors [legacy feature]\n");
fprintf(stderr, " -dither ordered Use ordered dithering when quantizing colors\n");
fprintf(stderr, " [legacy feature]\n");
fprintf(stderr, " -icc FILE Extract ICC profile to FILE\n");
#ifdef QUANT_2PASS_SUPPORTED
fprintf(stderr, " -map FILE Map to colors used in named image file\n");
fprintf(stderr, " -map FILE Quantize to colors used in named image file [legacy feature]\n");
#endif
fprintf(stderr, " -nosmooth Don't use high-quality upsampling\n");
fprintf(stderr, " -nosmooth Use faster, lower-quality upsampling\n");
#ifdef QUANT_1PASS_SUPPORTED
fprintf(stderr, " -onepass Use 1-pass quantization (fast, low quality)\n");
fprintf(stderr, " -onepass Use 1-pass color quantization (low quality) [legacy feature]\n");
#endif
fprintf(stderr, " -maxmemory N Maximum memory to use (in kbytes)\n");
fprintf(stderr, " -maxscans N Maximum number of scans to allow in input file\n");
fprintf(stderr, " -outfile name Specify name for output file\n");
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
fprintf(stderr, " -memsrc Load input file into memory before decompressing\n");
#endif
fprintf(stderr, " -report Report decompression progress\n");
fprintf(stderr, " -skip Y0,Y1 Decompress all rows except those between Y0 and Y1 (inclusive)\n");
fprintf(stderr, " -crop WxH+X+Y Decompress only a rectangular subregion of the image\n");
fprintf(stderr, " [requires PBMPLUS (PPM/PGM), GIF, or Targa output format]\n");
fprintf(stderr, " -strict Treat all warnings as fatal\n");
fprintf(stderr, " -verbose or -debug Emit debug output\n");
fprintf(stderr, " -version Print version information and exit\n");
exit(EXIT_FAILURE);
@@ -180,8 +179,8 @@ usage (void)
LOCAL(int)
parse_switches (j_decompress_ptr cinfo, int argc, char **argv,
int last_file_arg_seen, boolean for_real)
parse_switches(j_decompress_ptr cinfo, int argc, char **argv,
int last_file_arg_seen, boolean for_real)
/* Parse optional switches.
* Returns argv[] index of first file-name argument (== argc if none).
* Any file names with indexes <= last_file_arg_seen are ignored;
@@ -196,10 +195,14 @@ parse_switches (j_decompress_ptr cinfo, int argc, char **argv,
/* Set up default JPEG parameters. */
requested_fmt = DEFAULT_FMT; /* set default output file format */
icc_filename = NULL;
max_scans = 0;
outfilename = NULL;
memsrc = FALSE;
report = FALSE;
skip = FALSE;
crop = FALSE;
strict = FALSE;
cinfo->err->trace_level = 0;
/* Scan command line options, adjust parameters */
@@ -217,7 +220,7 @@ parse_switches (j_decompress_ptr cinfo, int argc, char **argv,
arg++; /* advance past switch marker character */
if (keymatch(arg, "bmp", 1)) {
/* BMP output format. */
/* BMP output format (Windows flavor). */
requested_fmt = FMT_BMP;
} else if (keymatch(arg, "colors", 1) || keymatch(arg, "colours", 1) ||
@@ -263,10 +266,11 @@ parse_switches (j_decompress_ptr cinfo, int argc, char **argv,
/* On first -d, print version identification */
static boolean printed_version = FALSE;
if (! printed_version) {
if (!printed_version) {
fprintf(stderr, "%s version %s (build %s)\n",
PACKAGE_NAME, VERSION, BUILD);
fprintf(stderr, "%s\n\n", JCOPYRIGHT);
fprintf(stderr, JCOPYRIGHT1);
fprintf(stderr, JCOPYRIGHT2 "\n");
fprintf(stderr, "Emulating The Independent JPEG Group's software, version %s\n\n",
JVERSION);
printed_version = TRUE;
@@ -282,16 +286,21 @@ parse_switches (j_decompress_ptr cinfo, int argc, char **argv,
/* Select recommended processing options for quick-and-dirty output. */
cinfo->two_pass_quantize = FALSE;
cinfo->dither_mode = JDITHER_ORDERED;
if (! cinfo->quantize_colors) /* don't override an earlier -colors */
if (!cinfo->quantize_colors) /* don't override an earlier -colors */
cinfo->desired_number_of_colors = 216;
cinfo->dct_method = JDCT_FASTEST;
cinfo->do_fancy_upsampling = FALSE;
} else if (keymatch(arg, "gif", 1)) {
/* GIF output format. */
/* GIF output format (LZW-compressed). */
requested_fmt = FMT_GIF;
} else if (keymatch(arg, "grayscale", 2) || keymatch(arg, "greyscale",2)) {
} else if (keymatch(arg, "gif0", 4)) {
/* GIF output format (uncompressed). */
requested_fmt = FMT_GIF0;
} else if (keymatch(arg, "grayscale", 2) ||
keymatch(arg, "greyscale", 2)) {
/* Force monochrome output. */
cinfo->out_color_space = JCS_GRAYSCALE;
@@ -303,6 +312,15 @@ parse_switches (j_decompress_ptr cinfo, int argc, char **argv,
/* Force RGB565 output. */
cinfo->out_color_space = JCS_RGB565;
} else if (keymatch(arg, "icc", 1)) {
/* Set ICC filename. */
if (++argn >= argc) /* advance to next argument */
usage();
icc_filename = argv[argn];
#ifdef SAVE_MARKERS_SUPPORTED
jpeg_save_markers(cinfo, JPEG_APP0 + 2, 0xFFFF);
#endif
} else if (keymatch(arg, "map", 3)) {
/* Quantize to a color map taken from an input file. */
if (++argn >= argc) /* advance to next argument */
@@ -315,7 +333,10 @@ parse_switches (j_decompress_ptr cinfo, int argc, char **argv,
fprintf(stderr, "%s: can't open %s\n", progname, argv[argn]);
exit(EXIT_FAILURE);
}
read_color_map(cinfo, mapfile);
if (cinfo->data_precision == 12)
read_color_map_12(cinfo, mapfile);
else
read_color_map(cinfo, mapfile);
fclose(mapfile);
cinfo->quantize_colors = TRUE;
#else
@@ -336,6 +357,12 @@ parse_switches (j_decompress_ptr cinfo, int argc, char **argv,
lval *= 1000L;
cinfo->mem->max_memory_to_use = lval * 1000L;
} else if (keymatch(arg, "maxscans", 4)) {
if (++argn >= argc) /* advance to next argument */
usage();
if (sscanf(argv[argn], "%u", &max_scans) != 1)
usage();
} else if (keymatch(arg, "nosmooth", 3)) {
/* Suppress fancy upsampling */
cinfo->do_fancy_upsampling = FALSE;
@@ -356,23 +383,16 @@ parse_switches (j_decompress_ptr cinfo, int argc, char **argv,
} else if (keymatch(arg, "memsrc", 2)) {
/* Use in-memory source manager */
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
memsrc = TRUE;
#else
fprintf(stderr, "%s: sorry, in-memory source manager was not compiled in\n",
progname);
exit(EXIT_FAILURE);
#endif
} else if (keymatch(arg, "pnm", 1) || keymatch(arg, "ppm", 1)) {
/* PPM/PGM output format. */
requested_fmt = FMT_PPM;
} else if (keymatch(arg, "rle", 1)) {
/* RLE output format. */
requested_fmt = FMT_RLE;
} else if (keymatch(arg, "report", 2)) {
report = TRUE;
} else if (keymatch(arg, "scale", 2)) {
} else if (keymatch(arg, "scale", 1)) {
/* Scale the output image by a fraction M/N. */
if (++argn >= argc) /* advance to next argument */
usage();
@@ -381,22 +401,34 @@ parse_switches (j_decompress_ptr cinfo, int argc, char **argv,
usage();
} else if (keymatch(arg, "skip", 2)) {
int temp_start = -1, temp_end = -1;
if (++argn >= argc)
usage();
if (sscanf(argv[argn], "%u,%u", &skip_start, &skip_end) != 2 ||
skip_start > skip_end)
if (sscanf(argv[argn], "%d,%d", &temp_start, &temp_end) != 2 ||
temp_start < 0 || temp_end < 0 || temp_start > temp_end)
usage();
skip = TRUE;
skip_start = temp_start;
skip_end = temp_end;
} else if (keymatch(arg, "crop", 2)) {
int temp_width = -1, temp_height = -1, temp_x = -1, temp_y = -1;
char c;
if (++argn >= argc)
usage();
if (sscanf(argv[argn], "%u%c%u+%u+%u", &crop_width, &c, &crop_height,
&crop_x, &crop_y) != 5 ||
(c != 'X' && c != 'x') || crop_width < 1 || crop_height < 1)
if (sscanf(argv[argn], "%d%c%d+%d+%d", &temp_width, &c, &temp_height,
&temp_x, &temp_y) != 5 ||
(c != 'X' && c != 'x') || temp_width < 1 || temp_height < 1 ||
temp_x < 0 || temp_y < 0)
usage();
crop = TRUE;
crop_width = temp_width;
crop_height = temp_height;
crop_x = temp_x;
crop_y = temp_y;
} else if (keymatch(arg, "strict", 2)) {
strict = TRUE;
} else if (keymatch(arg, "targa", 1)) {
/* Targa output format. */
@@ -419,22 +451,22 @@ parse_switches (j_decompress_ptr cinfo, int argc, char **argv,
*/
LOCAL(unsigned int)
jpeg_getc (j_decompress_ptr cinfo)
jpeg_getc(j_decompress_ptr cinfo)
/* Read next byte */
{
struct jpeg_source_mgr *datasrc = cinfo->src;
if (datasrc->bytes_in_buffer == 0) {
if (! (*datasrc->fill_input_buffer) (cinfo))
if (!(*datasrc->fill_input_buffer) (cinfo))
ERREXIT(cinfo, JERR_CANT_SUSPEND);
}
datasrc->bytes_in_buffer--;
return GETJOCTET(*datasrc->next_input_byte++);
return *datasrc->next_input_byte++;
}
METHODDEF(boolean)
print_text_marker (j_decompress_ptr cinfo)
print_text_marker(j_decompress_ptr cinfo)
{
boolean traceit = (cinfo->err->trace_level >= 1);
long length;
@@ -447,10 +479,10 @@ print_text_marker (j_decompress_ptr cinfo)
if (traceit) {
if (cinfo->unread_marker == JPEG_COM)
fprintf(stderr, "Comment, length %ld:\n", (long) length);
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);
cinfo->unread_marker - JPEG_APP0, (long)length);
}
while (--length >= 0) {
@@ -484,18 +516,29 @@ print_text_marker (j_decompress_ptr cinfo)
}
METHODDEF(void)
my_emit_message(j_common_ptr cinfo, int msg_level)
{
if (msg_level < 0) {
/* Treat warning as fatal */
cinfo->err->error_exit(cinfo);
} else {
if (cinfo->err->trace_level >= msg_level)
cinfo->err->output_message(cinfo);
}
}
/*
* The main program.
*/
int
main (int argc, char **argv)
main(int argc, char **argv)
{
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
#ifdef PROGRESS_REPORT
struct cdjpeg_progress_mgr progress;
#endif
int file_index;
djpeg_dest_ptr dest_mgr = NULL;
FILE *input_file;
@@ -504,11 +547,6 @@ main (int argc, char **argv)
unsigned long insize = 0;
JDIMENSION num_scanlines;
/* On Mac, fetch a command line. */
#ifdef USE_CCOMMAND
argc = ccommand(&argv);
#endif
progname = argv[0];
if (progname == NULL || progname[0] == 0)
progname = "djpeg"; /* in case C library doesn't provide it */
@@ -528,7 +566,7 @@ main (int argc, char **argv)
* but don't try to override APP0 or APP14 this way (see libjpeg.txt).
*/
jpeg_set_marker_processor(&cinfo, JPEG_COM, print_text_marker);
jpeg_set_marker_processor(&cinfo, JPEG_APP0+12, print_text_marker);
jpeg_set_marker_processor(&cinfo, JPEG_APP0 + 12, print_text_marker);
/* Scan command line to find file names. */
/* It is convenient to use just one switch-parsing routine, but the switch
@@ -540,17 +578,20 @@ main (int argc, char **argv)
file_index = parse_switches(&cinfo, argc, argv, 0, FALSE);
if (strict)
jerr.emit_message = my_emit_message;
#ifdef TWO_FILE_COMMANDLINE
/* Must have either -outfile switch or explicit output file name */
if (outfilename == NULL) {
if (file_index != argc-2) {
if (file_index != argc - 2) {
fprintf(stderr, "%s: must name one input and one output file\n",
progname);
usage();
}
outfilename = argv[file_index+1];
outfilename = argv[file_index + 1];
} else {
if (file_index != argc-1) {
if (file_index != argc - 1) {
fprintf(stderr, "%s: must name one input and one output file\n",
progname);
usage();
@@ -558,7 +599,7 @@ main (int argc, char **argv)
}
#else
/* Unix style: expect zero or one file name */
if (file_index < argc-1) {
if (file_index < argc - 1) {
fprintf(stderr, "%s: only one input file\n", progname);
usage();
}
@@ -586,12 +627,13 @@ main (int argc, char **argv)
output_file = write_stdout();
}
#ifdef PROGRESS_REPORT
start_progress_monitor((j_common_ptr) &cinfo, &progress);
#endif
if (report || max_scans != 0) {
start_progress_monitor((j_common_ptr)&cinfo, &progress);
progress.report = report;
progress.max_scans = max_scans;
}
/* Specify data source for decompression */
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
if (memsrc) {
size_t nbytes;
do {
@@ -600,7 +642,7 @@ main (int argc, char **argv)
fprintf(stderr, "%s: memory allocation failure\n", progname);
exit(EXIT_FAILURE);
}
nbytes = JFREAD(input_file, &inbuffer[insize], INPUT_BUF_SIZE);
nbytes = fread(&inbuffer[insize], 1, INPUT_BUF_SIZE, input_file);
if (nbytes < INPUT_BUF_SIZE && ferror(input_file)) {
if (file_index < argc)
fprintf(stderr, "%s: can't read from %s\n", progname,
@@ -613,11 +655,10 @@ main (int argc, char **argv)
fprintf(stderr, "Compressed size: %lu bytes\n", insize);
jpeg_mem_src(&cinfo, inbuffer, insize);
} else
#endif
jpeg_stdio_src(&cinfo, input_file);
/* Read file header, set default decompression parameters */
(void) jpeg_read_header(&cinfo, TRUE);
(void)jpeg_read_header(&cinfo, TRUE);
/* Adjust default decompression parameters by re-parsing the options */
file_index = parse_switches(&cinfo, argc, argv, 0, TRUE);
@@ -628,25 +669,37 @@ main (int argc, char **argv)
switch (requested_fmt) {
#ifdef BMP_SUPPORTED
case FMT_BMP:
dest_mgr = jinit_write_bmp(&cinfo, FALSE);
dest_mgr = jinit_write_bmp(&cinfo, FALSE, TRUE);
break;
case FMT_OS2:
dest_mgr = jinit_write_bmp(&cinfo, TRUE);
dest_mgr = jinit_write_bmp(&cinfo, TRUE, TRUE);
break;
#endif
#ifdef GIF_SUPPORTED
case FMT_GIF:
dest_mgr = jinit_write_gif(&cinfo);
if (cinfo.data_precision == 16)
ERREXIT1(&cinfo, JERR_BAD_PRECISION, cinfo.data_precision);
else if (cinfo.data_precision == 12)
dest_mgr = j12init_write_gif(&cinfo, TRUE);
else
dest_mgr = jinit_write_gif(&cinfo, TRUE);
break;
case FMT_GIF0:
dest_mgr = jinit_write_gif(&cinfo, FALSE);
break;
#endif
#ifdef PPM_SUPPORTED
case FMT_PPM:
dest_mgr = jinit_write_ppm(&cinfo);
break;
if (cinfo.data_precision == 16)
#ifdef D_LOSSLESS_SUPPORTED
dest_mgr = j16init_write_ppm(&cinfo);
#else
ERREXIT1(&cinfo, JERR_BAD_PRECISION, cinfo.data_precision);
#endif
#ifdef RLE_SUPPORTED
case FMT_RLE:
dest_mgr = jinit_write_rle(&cinfo);
else if (cinfo.data_precision == 12)
dest_mgr = j12init_write_ppm(&cinfo);
else
dest_mgr = jinit_write_ppm(&cinfo);
break;
#endif
#ifdef TARGA_SUPPORTED
@@ -661,7 +714,7 @@ main (int argc, char **argv)
dest_mgr->output_file = output_file;
/* Start decompressor */
(void) jpeg_start_decompress(&cinfo);
(void)jpeg_start_decompress(&cinfo);
/* Skip rows */
if (skip) {
@@ -672,7 +725,7 @@ main (int argc, char **argv)
* that skip_start <= skip_end.
*/
if (skip_end > cinfo.output_height - 1) {
fprintf(stderr, "%s: skip region exceeds image height %d\n", progname,
fprintf(stderr, "%s: skip region exceeds image height %u\n", progname,
cinfo.output_height);
exit(EXIT_FAILURE);
}
@@ -685,17 +738,44 @@ main (int argc, char **argv)
(*dest_mgr->start_output) (&cinfo, dest_mgr);
cinfo.output_height = tmp;
/* Process data */
while (cinfo.output_scanline < skip_start) {
num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer,
dest_mgr->buffer_height);
(*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines);
}
jpeg_skip_scanlines(&cinfo, skip_end - skip_start + 1);
while (cinfo.output_scanline < cinfo.output_height) {
num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer,
dest_mgr->buffer_height);
(*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines);
if (cinfo.data_precision == 16)
ERREXIT(&cinfo, JERR_NOTIMPL);
else if (cinfo.data_precision == 12) {
/* Process data */
while (cinfo.output_scanline < skip_start) {
num_scanlines = jpeg12_read_scanlines(&cinfo, dest_mgr->buffer12,
dest_mgr->buffer_height);
(*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines);
}
if ((tmp = jpeg12_skip_scanlines(&cinfo, skip_end - skip_start + 1)) !=
skip_end - skip_start + 1) {
fprintf(stderr, "%s: jpeg12_skip_scanlines() returned %u rather than %u\n",
progname, tmp, skip_end - skip_start + 1);
exit(EXIT_FAILURE);
}
while (cinfo.output_scanline < cinfo.output_height) {
num_scanlines = jpeg12_read_scanlines(&cinfo, dest_mgr->buffer12,
dest_mgr->buffer_height);
(*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines);
}
} else {
/* Process data */
while (cinfo.output_scanline < skip_start) {
num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer,
dest_mgr->buffer_height);
(*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines);
}
if ((tmp = jpeg_skip_scanlines(&cinfo, skip_end - skip_start + 1)) !=
skip_end - skip_start + 1) {
fprintf(stderr, "%s: jpeg_skip_scanlines() returned %u rather than %u\n",
progname, tmp, skip_end - skip_start + 1);
exit(EXIT_FAILURE);
}
while (cinfo.output_scanline < cinfo.output_height) {
num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer,
dest_mgr->buffer_height);
(*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines);
}
}
/* Decompress a subregion */
@@ -705,17 +785,23 @@ main (int argc, char **argv)
/* Check for valid crop dimensions. We cannot check these values until
* after jpeg_start_decompress() is called.
*/
if (crop_x + crop_width > cinfo.output_width ||
crop_y + crop_height > cinfo.output_height) {
fprintf(stderr, "%s: crop dimensions exceed image dimensions %d x %d\n",
if ((unsigned long long)crop_x + crop_width > cinfo.output_width ||
(unsigned long long)crop_y + crop_height > cinfo.output_height) {
fprintf(stderr, "%s: crop dimensions exceed image dimensions %u x %u\n",
progname, cinfo.output_width, cinfo.output_height);
exit(EXIT_FAILURE);
}
jpeg_crop_scanline(&cinfo, &crop_x, &crop_width);
((ppm_dest_ptr) dest_mgr)->buffer_width = cinfo.output_width *
cinfo.out_color_components *
sizeof(JSAMPLE);
if (cinfo.data_precision == 16)
ERREXIT(&cinfo, JERR_NOTIMPL);
else if (cinfo.data_precision == 12)
jpeg12_crop_scanline(&cinfo, &crop_x, &crop_width);
else
jpeg_crop_scanline(&cinfo, &crop_x, &crop_width);
if (dest_mgr->calc_buffer_dimensions)
(*dest_mgr->calc_buffer_dimensions) (&cinfo, dest_mgr);
else
ERREXIT(&cinfo, JERR_UNSUPPORTED_FORMAT);
/* Write output file header. This is a hack to ensure that the destination
* manager creates an output image of the proper size.
@@ -725,41 +811,118 @@ main (int argc, char **argv)
(*dest_mgr->start_output) (&cinfo, dest_mgr);
cinfo.output_height = tmp;
/* Process data */
jpeg_skip_scanlines(&cinfo, crop_y);
while (cinfo.output_scanline < crop_y + crop_height) {
num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer,
dest_mgr->buffer_height);
(*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines);
if (cinfo.data_precision == 16)
ERREXIT(&cinfo, JERR_NOTIMPL);
else if (cinfo.data_precision == 12) {
/* Process data */
if ((tmp = jpeg12_skip_scanlines(&cinfo, crop_y)) != crop_y) {
fprintf(stderr, "%s: jpeg12_skip_scanlines() returned %u rather than %u\n",
progname, tmp, crop_y);
exit(EXIT_FAILURE);
}
while (cinfo.output_scanline < crop_y + crop_height) {
num_scanlines = jpeg12_read_scanlines(&cinfo, dest_mgr->buffer12,
dest_mgr->buffer_height);
(*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines);
}
if ((tmp =
jpeg12_skip_scanlines(&cinfo, cinfo.output_height - crop_y -
crop_height)) !=
cinfo.output_height - crop_y - crop_height) {
fprintf(stderr, "%s: jpeg12_skip_scanlines() returned %u rather than %u\n",
progname, tmp, cinfo.output_height - crop_y - crop_height);
exit(EXIT_FAILURE);
}
} else {
/* Process data */
if ((tmp = jpeg_skip_scanlines(&cinfo, crop_y)) != crop_y) {
fprintf(stderr, "%s: jpeg_skip_scanlines() returned %u rather than %u\n",
progname, tmp, crop_y);
exit(EXIT_FAILURE);
}
while (cinfo.output_scanline < crop_y + crop_height) {
num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer,
dest_mgr->buffer_height);
(*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines);
}
if ((tmp =
jpeg_skip_scanlines(&cinfo,
cinfo.output_height - crop_y - crop_height)) !=
cinfo.output_height - crop_y - crop_height) {
fprintf(stderr, "%s: jpeg_skip_scanlines() returned %u rather than %u\n",
progname, tmp, cinfo.output_height - crop_y - crop_height);
exit(EXIT_FAILURE);
}
}
jpeg_skip_scanlines(&cinfo, cinfo.output_height - crop_y - crop_height);
/* Normal full-image decompress */
} else {
/* Write output file header */
(*dest_mgr->start_output) (&cinfo, dest_mgr);
/* Process data */
while (cinfo.output_scanline < cinfo.output_height) {
num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer,
dest_mgr->buffer_height);
(*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines);
if (cinfo.data_precision == 16) {
#ifdef D_LOSSLESS_SUPPORTED
/* Process data */
while (cinfo.output_scanline < cinfo.output_height) {
num_scanlines = jpeg16_read_scanlines(&cinfo, dest_mgr->buffer16,
dest_mgr->buffer_height);
(*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines);
}
#else
ERREXIT1(&cinfo, JERR_BAD_PRECISION, cinfo.data_precision);
#endif
} else if (cinfo.data_precision == 12) {
/* Process data */
while (cinfo.output_scanline < cinfo.output_height) {
num_scanlines = jpeg12_read_scanlines(&cinfo, dest_mgr->buffer12,
dest_mgr->buffer_height);
(*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines);
}
} else {
/* Process data */
while (cinfo.output_scanline < cinfo.output_height) {
num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer,
dest_mgr->buffer_height);
(*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines);
}
}
}
#ifdef PROGRESS_REPORT
/* Hack: count final pass as done in case finish_output does an extra pass.
* The library won't have updated completed_passes.
*/
progress.pub.completed_passes = progress.pub.total_passes;
#endif
if (report || max_scans != 0)
progress.pub.completed_passes = progress.pub.total_passes;
if (icc_filename != NULL) {
FILE *icc_file;
JOCTET *icc_profile;
unsigned int icc_len;
if ((icc_file = fopen(icc_filename, WRITE_BINARY)) == NULL) {
fprintf(stderr, "%s: can't open %s\n", progname, icc_filename);
exit(EXIT_FAILURE);
}
if (jpeg_read_icc_profile(&cinfo, &icc_profile, &icc_len)) {
if (fwrite(icc_profile, icc_len, 1, icc_file) < 1) {
fprintf(stderr, "%s: can't read ICC profile from %s\n", progname,
icc_filename);
free(icc_profile);
fclose(icc_file);
exit(EXIT_FAILURE);
}
free(icc_profile);
fclose(icc_file);
} else if (cinfo.err->msg_code != JWRN_BOGUS_ICC)
fprintf(stderr, "%s: no ICC profile data in JPEG file\n", progname);
}
/* Finish decompression and release memory.
* I must do it in this order because output module has allocated memory
* of lifespan JPOOL_IMAGE; it needs to finish before releasing memory.
*/
(*dest_mgr->finish_output) (&cinfo, dest_mgr);
(void) jpeg_finish_decompress(&cinfo);
(void)jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
/* Close files, if we opened them */
@@ -768,11 +931,10 @@ main (int argc, char **argv)
if (output_file != stdout)
fclose(output_file);
#ifdef PROGRESS_REPORT
end_progress_monitor((j_common_ptr) &cinfo);
#endif
if (report || max_scans != 0)
end_progress_monitor((j_common_ptr)&cinfo);
if (memsrc && inbuffer != NULL)
if (memsrc)
free(inbuffer);
/* All done. */

View File

@@ -1,18 +1,17 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.3.1"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>TurboJPEG: Data Structures</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
$(document).ready(function() { searchBox.OnSelectItem(0); });
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="doxygen-extra.css" rel="stylesheet" type="text/css"/>
</head>
@@ -21,10 +20,9 @@
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td style="padding-left: 0.5em;">
<div id="projectname">TurboJPEG
&#160;<span id="projectnumber">1.5</span>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">TurboJPEG<span id="projectnumber">&#160;3.0.1</span>
</div>
</td>
</tr>
@@ -32,73 +30,60 @@
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.3.1 -->
<!-- Generated by Doxygen 1.9.8 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search/",'.html');
/* @license-end */
</script>
<div id="navrow1" class="tabs">
<ul class="tablist">
<li><a href="index.html"><span>Main&#160;Page</span></a></li>
<li><a href="modules.html"><span>Modules</span></a></li>
<li class="current"><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
<li>
<div id="MSearchBox" class="MSearchBoxInactive">
<span class="left">
<img id="MSearchSelect" src="search/mag_sel.png"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
alt=""/>
<input type="text" id="MSearchField" value="Search" accesskey="S"
onfocus="searchBox.OnSearchFieldFocus(true)"
onblur="searchBox.OnSearchFieldFocus(false)"
onkeyup="searchBox.OnSearchFieldChange(event)"/>
</span><span class="right">
<a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
</span>
</div>
</li>
</ul>
</div>
<div id="navrow2" class="tabs2">
<ul class="tablist">
<li class="current"><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
<li><a href="classes.html"><span>Data&#160;Structure&#160;Index</span></a></li>
<li><a href="functions.html"><span>Data&#160;Fields</span></a></li>
</ul>
</div>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
</div><!-- top -->
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark">&#160;</span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark">&#160;</span>Data Structures</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark">&#160;</span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark">&#160;</span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark">&#160;</span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark">&#160;</span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark">&#160;</span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark">&#160;</span>Groups</a></div>
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
<div id="MSearchResults">
<div class="SRPage">
<div id="SRIndex">
<div id="SRResults"></div>
<div class="SRStatus" id="Loading">Loading...</div>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
</div>
</div>
</div>
</div>
<div class="header">
<div class="headertitle">
<div class="title">Data Structures</div> </div>
<div class="headertitle"><div class="title">Data Structures</div></div>
</div><!--header-->
<div class="contents">
<div class="textblock">Here are the data structures with brief descriptions:</div><div class="directory">
<table class="directory">
<tr id="row_0_" class="even"><td class="entry"><img src="ftv2node.png" alt="o" width="16" height="22" /><img src="ftv2cl.png" alt="C" width="24" height="22" /><a class="el" href="structtjregion.html" target="_self">tjregion</a></td><td class="desc">Cropping region</td></tr>
<tr id="row_1_"><td class="entry"><img src="ftv2node.png" alt="o" width="16" height="22" /><img src="ftv2cl.png" alt="C" width="24" height="22" /><a class="el" href="structtjscalingfactor.html" target="_self">tjscalingfactor</a></td><td class="desc">Scaling factor</td></tr>
<tr id="row_2_" class="even"><td class="entry"><img src="ftv2lastnode.png" alt="\" width="16" height="22" /><img src="ftv2cl.png" alt="C" width="24" height="22" /><a class="el" href="structtjtransform.html" target="_self">tjtransform</a></td><td class="desc">Lossless transform</td></tr>
<tr id="row_0_" class="even"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structtjregion.html" target="_self">tjregion</a></td><td class="desc">Cropping region </td></tr>
<tr id="row_1_" class="odd"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structtjscalingfactor.html" target="_self">tjscalingfactor</a></td><td class="desc">Scaling factor </td></tr>
<tr id="row_2_" class="even"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structtjtransform.html" target="_self">tjtransform</a></td><td class="desc">Lossless transform </td></tr>
</table>
</div><!-- directory -->
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.3.1
Generated by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.8
</small></address>
</body>
</html>

BIN
doc/html/bc_sd.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 635 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 B

View File

@@ -1,18 +1,17 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.3.1"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>TurboJPEG: Data Structure Index</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
$(document).ready(function() { searchBox.OnSelectItem(0); });
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="doxygen-extra.css" rel="stylesheet" type="text/css"/>
</head>
@@ -21,10 +20,9 @@
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td style="padding-left: 0.5em;">
<div id="projectname">TurboJPEG
&#160;<span id="projectnumber">1.5</span>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">TurboJPEG<span id="projectnumber">&#160;3.0.1</span>
</div>
</td>
</tr>
@@ -32,75 +30,59 @@
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.3.1 -->
<!-- Generated by Doxygen 1.9.8 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search/",'.html');
/* @license-end */
</script>
<div id="navrow1" class="tabs">
<ul class="tablist">
<li><a href="index.html"><span>Main&#160;Page</span></a></li>
<li><a href="modules.html"><span>Modules</span></a></li>
<li class="current"><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
<li>
<div id="MSearchBox" class="MSearchBoxInactive">
<span class="left">
<img id="MSearchSelect" src="search/mag_sel.png"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
alt=""/>
<input type="text" id="MSearchField" value="Search" accesskey="S"
onfocus="searchBox.OnSearchFieldFocus(true)"
onblur="searchBox.OnSearchFieldFocus(false)"
onkeyup="searchBox.OnSearchFieldChange(event)"/>
</span><span class="right">
<a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
</span>
</div>
</li>
</ul>
</div>
<div id="navrow2" class="tabs2">
<ul class="tablist">
<li><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
<li class="current"><a href="classes.html"><span>Data&#160;Structure&#160;Index</span></a></li>
<li><a href="functions.html"><span>Data&#160;Fields</span></a></li>
</ul>
</div>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
</div><!-- top -->
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark">&#160;</span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark">&#160;</span>Data Structures</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark">&#160;</span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark">&#160;</span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark">&#160;</span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark">&#160;</span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark">&#160;</span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark">&#160;</span>Groups</a></div>
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
<div id="MSearchResults">
<div class="SRPage">
<div id="SRIndex">
<div id="SRResults"></div>
<div class="SRStatus" id="Loading">Loading...</div>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
</div>
</div>
</div>
</div>
<div class="header">
<div class="headertitle">
<div class="title">Data Structure Index</div> </div>
<div class="headertitle"><div class="title">Data Structure Index</div></div>
</div><!--header-->
<div class="contents">
<div class="qindex"><a class="qindex" href="#letter_T">T</a></div>
<table style="margin: 10px; white-space: nowrap;" align="center" width="95%" border="0" cellspacing="0" cellpadding="0">
<tr><td rowspan="2" valign="bottom"><a name="letter_T"></a><table border="0" cellspacing="0" cellpadding="0"><tr><td><div class="ah">&#160;&#160;T&#160;&#160;</div></td></tr></table>
</td><td valign="top"><a class="el" href="structtjscalingfactor.html">tjscalingfactor</a>&#160;&#160;&#160;</td><td valign="top"><a class="el" href="structtjtransform.html">tjtransform</a>&#160;&#160;&#160;</td><td></td></tr>
<tr><td></td><td></td><td></td></tr>
<tr><td valign="top"><a class="el" href="structtjregion.html">tjregion</a>&#160;&#160;&#160;</td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td></tr>
</table>
<div class="qindex"><a class="qindex" href="#letter_T">T</a></div>
<div class="classindex">
<dl class="classindex even">
<dt class="alphachar"><a id="letter_T" name="letter_T">T</a></dt>
<dd><a class="el" href="structtjregion.html">tjregion</a></dd><dd><a class="el" href="structtjscalingfactor.html">tjscalingfactor</a></dd><dd><a class="el" href="structtjtransform.html">tjtransform</a></dd></dl>
</div>
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.3.1
Generated by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.8
</small></address>
</body>
</html>

12
doc/html/doc.svg Normal file
View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"https://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" width="16" height="24" viewBox="0 0 80 60" id="doc" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve">
<g style="fill:#4665A2">
<path d="m 14,-1.1445312 c -2.824372,0 -5.1445313,2.320159 -5.1445312,5.1445312 v 72 c 0,2.824372 2.3201592,5.144531 5.1445312,5.144531 h 52 c 2.824372,0 5.144531,-2.320159 5.144531,-5.144531 V 23.699219 a 1.1447968,1.1447968 0 0 0 -0.01563,-0.1875 C 70.977847,22.605363 70.406495,21.99048 70.007812,21.591797 L 48.208984,-0.20898438 C 47.606104,-0.81186474 46.804652,-1.1445313 46,-1.1445312 Z m 1.144531,6.2890624 H 42.855469 V 24 c 0,1.724372 1.420159,3.144531 3.144531,3.144531 H 64.855469 V 74.855469 H 15.144531 Z m 34,4.4179688 L 60.4375,20.855469 H 49.144531 Z"/>
</g>
<g style="fill:#D8DFEE;stroke-width:0">
<path d="M 3.0307167,13.993174 V 7.0307167 h 2.7576792 2.7576792 v 1.8826151 c 0,1.2578262 0.0099,1.9287572 0.029818,2.0216512 0.03884,0.181105 0.168631,0.348218 0.33827,0.43554 l 0.1355017,0.06975 1.9598092,0.0079 1.959809,0.0078 v 4.749829 4.749829 H 8 3.0307167 Z" transform="matrix(5,0,0,5,0,-30)" />
<path d="M 9.8293515,9.0581469 V 7.9456453 l 1.1058025,1.1055492 c 0.608191,0.6080521 1.105802,1.1086775 1.105802,1.1125015 0,0.0038 -0.497611,0.007 -1.105802,0.007 H 9.8293515 Z" transform="matrix(5,0,0,5,0,-30)" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

12
doc/html/docd.svg Normal file
View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"https://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" width="16" height="24" viewBox="0 0 80 60" id="doc" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve">
<g style="fill:#C4CFE5">
<path d="m 14,-1.1445312 c -2.824372,0 -5.1445313,2.320159 -5.1445312,5.1445312 v 72 c 0,2.824372 2.3201592,5.144531 5.1445312,5.144531 h 52 c 2.824372,0 5.144531,-2.320159 5.144531,-5.144531 V 23.699219 a 1.1447968,1.1447968 0 0 0 -0.01563,-0.1875 C 70.977847,22.605363 70.406495,21.99048 70.007812,21.591797 L 48.208984,-0.20898438 C 47.606104,-0.81186474 46.804652,-1.1445313 46,-1.1445312 Z m 1.144531,6.2890624 H 42.855469 V 24 c 0,1.724372 1.420159,3.144531 3.144531,3.144531 H 64.855469 V 74.855469 H 15.144531 Z m 34,4.4179688 L 60.4375,20.855469 H 49.144531 Z"/>
</g>
<g style="fill:#4665A2;stroke-width:0">
<path d="M 3.0307167,13.993174 V 7.0307167 h 2.7576792 2.7576792 v 1.8826151 c 0,1.2578262 0.0099,1.9287572 0.029818,2.0216512 0.03884,0.181105 0.168631,0.348218 0.33827,0.43554 l 0.1355017,0.06975 1.9598092,0.0079 1.959809,0.0078 v 4.749829 4.749829 H 8 3.0307167 Z" transform="matrix(5,0,0,5,0,-30)" />
<path d="M 9.8293515,9.0581469 V 7.9456453 l 1.1058025,1.1055492 c 0.608191,0.6080521 1.105802,1.1086775 1.105802,1.1125015 0,0.0038 -0.497611,0.007 -1.105802,0.007 H 9.8293515 Z" transform="matrix(5,0,0,5,0,-30)" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -1,3 +1,7 @@
code {
color: #4665A2;
color: #4665A2;
}
th.markdownTableHeadNone {
color: black;
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

28
doc/html/doxygen.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -1,3 +1,27 @@
/*
@licstart The following is the entire license notice for the JavaScript code in this file.
The MIT License (MIT)
Copyright (C) 1997-2020 by Dimitri van Heesch
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@licend The above is the entire license notice for the JavaScript code in this file
*/
function toggleVisibility(linkObj)
{
var base = $(linkObj).attr('id');
@@ -15,7 +39,7 @@ function toggleVisibility(linkObj)
summary.hide();
$(linkObj).removeClass('closed').addClass('opened');
$(trigger).attr('src',src.substring(0,src.length-10)+'open.png');
}
}
return false;
}
@@ -23,20 +47,23 @@ function updateStripes()
{
$('table.directory tr').
removeClass('even').filter(':visible:even').addClass('even');
$('table.directory tr').
removeClass('odd').filter(':visible:odd').addClass('odd');
}
function toggleLevel(level)
{
$('table.directory tr').each(function(){
$('table.directory tr').each(function() {
var l = this.id.split('_').length-1;
var i = $('#img'+this.id.substring(3));
var a = $('#arr'+this.id.substring(3));
if (l<level+1) {
i.attr('src','ftv2folderopen.png');
a.attr('src','ftv2mnode.png');
i.removeClass('iconfopen iconfclosed').addClass('iconfopen');
a.html('&#9660;');
$(this).show();
} else if (l==level+1) {
i.attr('src','ftv2folderclosed.png');
a.attr('src','ftv2pnode.png');
i.removeClass('iconfclosed iconfopen').addClass('iconfclosed');
a.html('&#9658;');
$(this).show();
} else {
$(this).hide();
@@ -47,34 +74,33 @@ function toggleLevel(level)
function toggleFolder(id)
{
//The clicked row
// the clicked row
var currentRow = $('#row_'+id);
var currentRowImages = currentRow.find("img");
//All rows after the clicked row
// all rows after the clicked row
var rows = currentRow.nextAll("tr");
//Only match elements AFTER this one (can't hide elements before)
var childRows = rows.filter(function() {
var re = new RegExp('^row_'+id+'\\d+_$', "i"); //only one sub
return this.id.match(re);
});
var re = new RegExp('^row_'+id+'\\d+_$', "i"); //only one sub
//First row is visible we are HIDING
// only match elements AFTER this one (can't hide elements before)
var childRows = rows.filter(function() { return this.id.match(re); });
// first row is visible we are HIDING
if (childRows.filter(':first').is(':visible')===true) {
currentRowImages.filter("[id^=arr]").attr('src', 'ftv2pnode.png');
currentRowImages.filter("[id^=img]").attr('src', 'ftv2folderclosed.png');
rows.filter("[id^=row_"+id+"]").hide();
} else { //We are SHOWING
//All sub images
var childImages = childRows.find("img");
var childImg = childImages.filter("[id^=img]");
var childArr = childImages.filter("[id^=arr]");
currentRow.find("[id^=arr]").attr('src', 'ftv2mnode.png'); //open row
currentRow.find("[id^=img]").attr('src', 'ftv2folderopen.png'); //open row
childImg.attr('src','ftv2folderclosed.png'); //children closed
childArr.attr('src','ftv2pnode.png'); //children closed
// replace down arrow by right arrow for current row
var currentRowSpans = currentRow.find("span");
currentRowSpans.filter(".iconfopen").removeClass("iconfopen").addClass("iconfclosed");
currentRowSpans.filter(".arrow").html('&#9658;');
rows.filter("[id^=row_"+id+"]").hide(); // hide all children
} else { // we are SHOWING
// replace right arrow by down arrow for current row
var currentRowSpans = currentRow.find("span");
currentRowSpans.filter(".iconfclosed").removeClass("iconfclosed").addClass("iconfopen");
currentRowSpans.filter(".arrow").html('&#9660;');
// replace down arrows by right arrows for child rows
var childRowsSpans = childRows.find("span");
childRowsSpans.filter(".iconfopen").removeClass("iconfopen").addClass("iconfclosed");
childRowsSpans.filter(".arrow").html('&#9658;');
childRows.show(); //show all children
}
updateStripes();
@@ -95,3 +121,72 @@ function toggleInherit(id)
}
}
var opened=true;
// in case HTML_COLORSTYLE is LIGHT or DARK the vars will be replaced, so we write them out explicitly and use double quotes
var plusImg = [ "var(--fold-plus-image)", "var(--fold-plus-image-relpath)" ];
var minusImg = [ "var(--fold-minus-image)", "var(--fold-minus-image-relpath)" ];
// toggle all folding blocks
function codefold_toggle_all(relPath) {
if (opened) {
$('#fold_all').css('background-image',plusImg[relPath]);
$('div[id^=foldopen]').hide();
$('div[id^=foldclosed]').show();
} else {
$('#fold_all').css('background-image',minusImg[relPath]);
$('div[id^=foldopen]').show();
$('div[id^=foldclosed]').hide();
}
opened=!opened;
}
// toggle single folding block
function codefold_toggle(id) {
$('#foldopen'+id).toggle();
$('#foldclosed'+id).toggle();
}
function init_codefold(relPath) {
$('span[class=lineno]').css(
{'padding-right':'4px',
'margin-right':'2px',
'display':'inline-block',
'width':'54px',
'background':'linear-gradient(var(--fold-line-color),var(--fold-line-color)) no-repeat 46px/2px 100%'
});
// add global toggle to first line
$('span[class=lineno]:first').append('<span class="fold" id="fold_all" '+
'onclick="javascript:codefold_toggle_all('+relPath+');" '+
'style="background-image:'+minusImg[relPath]+';"></span>');
// add vertical lines to other rows
$('span[class=lineno]').not(':eq(0)').append('<span class="fold"></span>');
// add toggle controls to lines with fold divs
$('div[class=foldopen]').each(function() {
// extract specific id to use
var id = $(this).attr('id').replace('foldopen','');
// extract start and end foldable fragment attributes
var start = $(this).attr('data-start');
var end = $(this).attr('data-end');
// replace normal fold span with controls for the first line of a foldable fragment
$(this).find('span[class=fold]:first').replaceWith('<span class="fold" '+
'onclick="javascript:codefold_toggle(\''+id+'\');" '+
'style="background-image:'+minusImg[relPath]+';"></span>');
// append div for folded (closed) representation
$(this).after('<div id="foldclosed'+id+'" class="foldclosed" style="display:none;"></div>');
// extract the first line from the "open" section to represent closed content
var line = $(this).children().first().clone();
// remove any glow that might still be active on the original line
$(line).removeClass('glow');
if (start) {
// if line already ends with a start marker (e.g. trailing {), remove it
$(line).html($(line).html().replace(new RegExp('\\s*'+start+'\\s*$','g'),''));
}
// replace minus with plus symbol
$(line).find('span[class=fold]').css('background-image',plusImg[relPath]);
// append ellipsis
$(line).append(' '+start+'<a href="javascript:codefold_toggle(\''+id+'\')">&#8230;</a>'+end);
// insert constructed line into closed div
$('#foldclosed'+id).html(line);
});
}
/* @license-end */

11
doc/html/folderclosed.svg Normal file
View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"https://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" width="16" height="24" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve">
<g style="fill:#4665A2;">
<path d="M1,5.998l-0,16.002c-0,1.326 0.527,2.598 1.464,3.536c0.938,0.937 2.21,1.464 3.536,1.464c5.322,0 14.678,-0 20,0c1.326,0 2.598,-0.527 3.536,-1.464c0.937,-0.938 1.464,-2.21 1.464,-3.536c0,-3.486 0,-8.514 0,-12c0,-1.326 -0.527,-2.598 -1.464,-3.536c-0.938,-0.937 -2.21,-1.464 -3.536,-1.464c-0,0 -10.586,0 -10.586,0c0,-0 -3.707,-3.707 -3.707,-3.707c-0.187,-0.188 -0.442,-0.293 -0.707,-0.293l-5.002,0c-2.76,0 -4.998,2.238 -4.998,4.998Zm2,-0l-0,16.002c-0,0.796 0.316,1.559 0.879,2.121c0.562,0.563 1.325,0.879 2.121,0.879l20,0c0.796,0 1.559,-0.316 2.121,-0.879c0.563,-0.562 0.879,-1.325 0.879,-2.121c0,-3.486 0,-8.514 0,-12c0,-0.796 -0.316,-1.559 -0.879,-2.121c-0.562,-0.563 -1.325,-0.879 -2.121,-0.879c-7.738,0 -11,0 -11,0c-0.265,0 -0.52,-0.105 -0.707,-0.293c-0,0 -3.707,-3.707 -3.707,-3.707c-0,0 -4.588,0 -4.588,0c-1.656,0 -2.998,1.342 -2.998,2.998Z"/>
</g>
<g style="fill:#D8DFEE;stroke-width:0;">
<path d="M 5.6063709,24.951908 C 4.3924646,24.775461 3.4197129,23.899792 3.1031586,22.698521 L 3.0216155,22.389078 V 13.997725 5.6063709 L 3.1037477,5.2982247 C 3.3956682,4.2029881 4.1802788,3.412126 5.2787258,3.105917 5.5646428,3.0262132 5.6154982,3.0244963 8.0611641,3.0119829 l 2.4911989,-0.012746 1.932009,1.9300342 c 1.344142,1.3427669 1.976319,1.9498819 2.07763,1.9952626 0.137456,0.061571 0.474218,0.066269 6.006826,0.083795 l 5.861206,0.018568 0.29124,0.081916 c 1.094895,0.3079569 1.890116,1.109428 2.175567,2.192667 l 0.08154,0.3094425 V 16 22.389078 l -0.08154,0.309443 c -0.28446,1.079482 -1.086411,1.888085 -2.175567,2.193614 l -0.29124,0.0817 -10.302616,0.0049 c -5.700217,0.0027 -10.4001945,-0.0093 -10.5210471,-0.02684 z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"https://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" width="16" height="24" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve">
<g style="fill:#C4CFE5;">
<path d="M1,5.998l-0,16.002c-0,1.326 0.527,2.598 1.464,3.536c0.938,0.937 2.21,1.464 3.536,1.464c5.322,0 14.678,-0 20,0c1.326,0 2.598,-0.527 3.536,-1.464c0.937,-0.938 1.464,-2.21 1.464,-3.536c0,-3.486 0,-8.514 0,-12c0,-1.326 -0.527,-2.598 -1.464,-3.536c-0.938,-0.937 -2.21,-1.464 -3.536,-1.464c-0,0 -10.586,0 -10.586,0c0,-0 -3.707,-3.707 -3.707,-3.707c-0.187,-0.188 -0.442,-0.293 -0.707,-0.293l-5.002,0c-2.76,0 -4.998,2.238 -4.998,4.998Zm2,-0l-0,16.002c-0,0.796 0.316,1.559 0.879,2.121c0.562,0.563 1.325,0.879 2.121,0.879l20,0c0.796,0 1.559,-0.316 2.121,-0.879c0.563,-0.562 0.879,-1.325 0.879,-2.121c0,-3.486 0,-8.514 0,-12c0,-0.796 -0.316,-1.559 -0.879,-2.121c-0.562,-0.563 -1.325,-0.879 -2.121,-0.879c-7.738,0 -11,0 -11,0c-0.265,0 -0.52,-0.105 -0.707,-0.293c-0,0 -3.707,-3.707 -3.707,-3.707c-0,0 -4.588,0 -4.588,0c-1.656,0 -2.998,1.342 -2.998,2.998Z"/>
</g>
<g style="fill:#4665A2;stroke-width:0;">
<path d="M 5.6063709,24.951908 C 4.3924646,24.775461 3.4197129,23.899792 3.1031586,22.698521 L 3.0216155,22.389078 V 13.997725 5.6063709 L 3.1037477,5.2982247 C 3.3956682,4.2029881 4.1802788,3.412126 5.2787258,3.105917 5.5646428,3.0262132 5.6154982,3.0244963 8.0611641,3.0119829 l 2.4911989,-0.012746 1.932009,1.9300342 c 1.344142,1.3427669 1.976319,1.9498819 2.07763,1.9952626 0.137456,0.061571 0.474218,0.066269 6.006826,0.083795 l 5.861206,0.018568 0.29124,0.081916 c 1.094895,0.3079569 1.890116,1.109428 2.175567,2.192667 l 0.08154,0.3094425 V 16 22.389078 l -0.08154,0.309443 c -0.28446,1.079482 -1.086411,1.888085 -2.175567,2.193614 l -0.29124,0.0817 -10.302616,0.0049 c -5.700217,0.0027 -10.4001945,-0.0093 -10.5210471,-0.02684 z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

17
doc/html/folderopen.svg Normal file
View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"https://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" width="16" height="24" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve">
<g style="fill:#4665A2;">
<path
d="M1,5.998l0,16.002c-0,1.326 0.527,2.598 1.464,3.536c0.938,0.937 2.21,1.464 3.536,1.464c5.322,0 14.678,-0 20,0c1.326,0 2.598,-0.527 3.536,-1.464c0.937,-0.938 1.464,-2.21 1.464,-3.536c0,-3.486 0,-8.514 0,-12c0,-1.326 -0.527,-2.598 -1.464,-3.536c-0.938,-0.937 -2.21,-1.464 -3.536,-1.464c-0,0 -10.586,0 -10.586,0c0,-0 -3.707,-3.707 -3.707,-3.707c-0.187,-0.188 -0.442,-0.293 -0.707,-0.293l-5.002,0c-2.76,0 -4.998,2.238 -4.998,4.998Zm28,14.415l-3.456,-5.925c-0.538,-0.921 -1.524,-1.488 -2.591,-1.488c-0,0 -12.905,0 -12.906,0c-1.067,0 -2.053,0.567 -2.591,1.488l-4.453,7.635c0.03,0.751 0.342,1.465 0.876,1.998c0.562,0.563 1.325,0.879 2.121,0.879l20,0c0.796,0 1.559,-0.316 2.121,-0.879c0.563,-0.562 0.879,-1.325 0.879,-2.121l0,-1.587Zm0,-3.969l0,-6.444c0,-0.796 -0.316,-1.559 -0.879,-2.121c-0.562,-0.563 -1.325,-0.879 -2.121,-0.879c-7.738,0 -11,0 -11,0c-0.265,0 -0.52,-0.105 -0.707,-0.293c-0,0 -3.707,-3.707 -3.707,-3.707c-0,0 -4.588,0 -4.588,0c-1.656,0 -2.998,1.342 -2.998,2.998l0,12.16l2.729,-4.677c0.896,-1.536 2.54,-2.481 4.318,-2.481c3.354,0 9.552,0 12.906,0c1.778,0 3.422,0.945 4.318,2.481l1.729,2.963Z"
id="path2" />
</g>
<g style="fill:#D8DFEE;stroke-width:0;">
<path
d="M 5.3879408,24.913408 C 4.1598821,24.650818 3.1571088,23.558656 3.053503,22.370876 L 3.0312746,22.116041 5.2606813,18.293515 C 6.486855,16.191126 7.5598351,14.372696 7.6450818,14.25256 8.0043056,13.746312 8.5423079,13.363007 9.2104664,13.137285 l 0.2548351,-0.08609 6.9294785,-0.0097 c 6.805096,-0.0095 6.934944,-0.0084 7.234011,0.06267 0.695577,0.165199 1.290483,0.557253 1.714887,1.130141 0.08158,0.110125 0.938747,1.556711 1.90481,3.214634 l 1.756479,3.014406 -0.0186,0.971942 c -0.01387,0.724723 -0.03365,1.032131 -0.07778,1.208575 -0.242792,0.970733 -0.88732,1.735415 -1.772382,2.102793 -0.58835,0.244217 0.247209,0.227436 -11.161974,0.224159 -9.0281537,-0.0026 -10.3636023,-0.0098 -10.5862902,-0.05746 z"
id="path199" /><path
d="M 3.0126385,11.849829 3.0235061,5.5881684 3.1020974,5.2969283 C 3.3478146,4.3863605 3.93576,3.6757372 4.756668,3.2971229 5.3293315,3.0330025 5.1813272,3.0450949 8.0130385,3.0310668 l 2.5522875,-0.012644 1.918693,1.9107086 c 1.404146,1.3983023 1.964459,1.9332518 2.089351,1.9947704 l 0.170657,0.084062 5.897611,0.019367 c 5.553257,0.018236 5.910365,0.023213 6.116041,0.085231 1.102257,0.3323708 1.857042,1.1184422 2.154229,2.2435244 0.05645,0.2137228 0.06373,0.5643981 0.07519,3.6220748 0.0076,2.032169 -5.42e-4,3.370979 -0.02041,3.349261 -0.0182,-0.0199 -0.414296,-0.691472 -0.880217,-1.492382 -0.46592,-0.80091 -0.93093,-1.577954 -1.033354,-1.726764 -0.735716,-1.0689 -1.983568,-1.844244 -3.315972,-2.060353 -0.280375,-0.04548 -1.345158,-0.05334 -7.238708,-0.05347 -4.713933,-1.09e-4 -6.9931825,0.01221 -7.1717862,0.03874 -1.3002273,0.193134 -2.4770512,0.889916 -3.283628,1.944192 -0.1076466,0.140705 -0.8359664,1.353438 -1.6184885,2.694963 L 3.0017709,18.11149 Z"
id="path201" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

12
doc/html/folderopend.svg Normal file
View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"https://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" width="16" height="24" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve">
<g style="fill:#C4CFE5;">
<path d="M1,5.998l0,16.002c-0,1.326 0.527,2.598 1.464,3.536c0.938,0.937 2.21,1.464 3.536,1.464c5.322,0 14.678,-0 20,0c1.326,0 2.598,-0.527 3.536,-1.464c0.937,-0.938 1.464,-2.21 1.464,-3.536c0,-3.486 0,-8.514 0,-12c0,-1.326 -0.527,-2.598 -1.464,-3.536c-0.938,-0.937 -2.21,-1.464 -3.536,-1.464c-0,0 -10.586,0 -10.586,0c0,-0 -3.707,-3.707 -3.707,-3.707c-0.187,-0.188 -0.442,-0.293 -0.707,-0.293l-5.002,0c-2.76,0 -4.998,2.238 -4.998,4.998Zm28,14.415l-3.456,-5.925c-0.538,-0.921 -1.524,-1.488 -2.591,-1.488c-0,0 -12.905,0 -12.906,0c-1.067,0 -2.053,0.567 -2.591,1.488l-4.453,7.635c0.03,0.751 0.342,1.465 0.876,1.998c0.562,0.563 1.325,0.879 2.121,0.879l20,0c0.796,0 1.559,-0.316 2.121,-0.879c0.563,-0.562 0.879,-1.325 0.879,-2.121l0,-1.587Zm0,-3.969l0,-6.444c0,-0.796 -0.316,-1.559 -0.879,-2.121c-0.562,-0.563 -1.325,-0.879 -2.121,-0.879c-7.738,0 -11,0 -11,0c-0.265,0 -0.52,-0.105 -0.707,-0.293c-0,0 -3.707,-3.707 -3.707,-3.707c-0,0 -4.588,0 -4.588,0c-1.656,0 -2.998,1.342 -2.998,2.998l0,12.16l2.729,-4.677c0.896,-1.536 2.54,-2.481 4.318,-2.481c3.354,0 9.552,0 12.906,0c1.778,0 3.422,0.945 4.318,2.481l1.729,2.963Z"/>
</g>
<g style="fill:#4665A2;stroke-width:0;">
<path d="M 5.3879408,24.913408 C 4.1598821,24.650818 3.1571088,23.558656 3.053503,22.370876 L 3.0312746,22.116041 5.2606813,18.293515 C 6.486855,16.191126 7.5598351,14.372696 7.6450818,14.25256 8.0043056,13.746312 8.5423079,13.363007 9.2104664,13.137285 l 0.2548351,-0.08609 6.9294785,-0.0097 c 6.805096,-0.0095 6.934944,-0.0084 7.234011,0.06267 0.695577,0.165199 1.290483,0.557253 1.714887,1.130141 0.08158,0.110125 0.938747,1.556711 1.90481,3.214634 l 1.756479,3.014406 -0.0186,0.971942 c -0.01387,0.724723 -0.03365,1.032131 -0.07778,1.208575 -0.242792,0.970733 -0.88732,1.735415 -1.772382,2.102793 -0.58835,0.244217 0.247209,0.227436 -11.161974,0.224159 -9.0281537,-0.0026 -10.3636023,-0.0098 -10.5862902,-0.05746 z" />
<path d="M 3.0126385,11.849829 3.0235061,5.5881684 3.1020974,5.2969283 C 3.3478146,4.3863605 3.93576,3.6757372 4.756668,3.2971229 5.3293315,3.0330025 5.1813272,3.0450949 8.0130385,3.0310668 l 2.5522875,-0.012644 1.918693,1.9107086 c 1.404146,1.3983023 1.964459,1.9332518 2.089351,1.9947704 l 0.170657,0.084062 5.897611,0.019367 c 5.553257,0.018236 5.910365,0.023213 6.116041,0.085231 1.102257,0.3323708 1.857042,1.1184422 2.154229,2.2435244 0.05645,0.2137228 0.06373,0.5643981 0.07519,3.6220748 0.0076,2.032169 -5.42e-4,3.370979 -0.02041,3.349261 -0.0182,-0.0199 -0.414296,-0.691472 -0.880217,-1.492382 -0.46592,-0.80091 -0.93093,-1.577954 -1.033354,-1.726764 -0.735716,-1.0689 -1.983568,-1.844244 -3.315972,-2.060353 -0.280375,-0.04548 -1.345158,-0.05334 -7.238708,-0.05347 -4.713933,-1.09e-4 -6.9931825,0.01221 -7.1717862,0.03874 -1.3002273,0.193134 -2.4770512,0.889916 -3.283628,1.944192 -0.1076466,0.140705 -0.8359664,1.353438 -1.6184885,2.694963 L 3.0017709,18.11149 Z" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 453 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 746 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 616 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 597 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 746 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 246 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 246 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 403 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 388 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 229 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 229 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 B

View File

@@ -1,18 +1,17 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.3.1"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>TurboJPEG: Data Fields</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
$(document).ready(function() { searchBox.OnSelectItem(0); });
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="doxygen-extra.css" rel="stylesheet" type="text/css"/>
</head>
@@ -21,10 +20,9 @@
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td style="padding-left: 0.5em;">
<div id="projectname">TurboJPEG
&#160;<span id="projectnumber">1.5</span>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">TurboJPEG<span id="projectnumber">&#160;3.0.1</span>
</div>
</td>
</tr>
@@ -32,103 +30,63 @@
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.3.1 -->
<!-- Generated by Doxygen 1.9.8 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search/",'.html');
/* @license-end */
</script>
<div id="navrow1" class="tabs">
<ul class="tablist">
<li><a href="index.html"><span>Main&#160;Page</span></a></li>
<li><a href="modules.html"><span>Modules</span></a></li>
<li class="current"><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
<li>
<div id="MSearchBox" class="MSearchBoxInactive">
<span class="left">
<img id="MSearchSelect" src="search/mag_sel.png"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
alt=""/>
<input type="text" id="MSearchField" value="Search" accesskey="S"
onfocus="searchBox.OnSearchFieldFocus(true)"
onblur="searchBox.OnSearchFieldFocus(false)"
onkeyup="searchBox.OnSearchFieldChange(event)"/>
</span><span class="right">
<a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
</span>
</div>
</li>
</ul>
</div>
<div id="navrow2" class="tabs2">
<ul class="tablist">
<li><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
<li><a href="classes.html"><span>Data&#160;Structure&#160;Index</span></a></li>
<li class="current"><a href="functions.html"><span>Data&#160;Fields</span></a></li>
</ul>
</div>
<div id="navrow3" class="tabs2">
<ul class="tablist">
<li class="current"><a href="functions.html"><span>All</span></a></li>
<li><a href="functions_vars.html"><span>Variables</span></a></li>
</ul>
</div>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
</div><!-- top -->
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark">&#160;</span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark">&#160;</span>Data Structures</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark">&#160;</span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark">&#160;</span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark">&#160;</span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark">&#160;</span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark">&#160;</span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark">&#160;</span>Groups</a></div>
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
<div id="MSearchResults">
<div class="SRPage">
<div id="SRIndex">
<div id="SRResults"></div>
<div class="SRStatus" id="Loading">Loading...</div>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
</div>
</div>
</div>
</div>
<div class="contents">
<div class="textblock">Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:</div><ul>
<li>customFilter
: <a class="el" href="structtjtransform.html#a43ee1bcdd2a8d7249a756774f78793c1">tjtransform</a>
</li>
<li>data
: <a class="el" href="structtjtransform.html#a688fe8f1a8ecc12a538d9e561cf338e3">tjtransform</a>
</li>
<li>denom
: <a class="el" href="structtjscalingfactor.html#aefbcdf3e9e62274b2d312c695f133ce3">tjscalingfactor</a>
</li>
<li>h
: <a class="el" href="structtjregion.html#aecefc45a26f4d8b60dd4d825c1710115">tjregion</a>
</li>
<li>num
: <a class="el" href="structtjscalingfactor.html#a9b011e57f981ee23083e2c1aa5e640ec">tjscalingfactor</a>
</li>
<li>op
: <a class="el" href="structtjtransform.html#a2525aab4ba6978a1c273f74fef50e498">tjtransform</a>
</li>
<li>options
: <a class="el" href="structtjtransform.html#ac0e74655baa4402209a21e1ae481c8f6">tjtransform</a>
</li>
<li>r
: <a class="el" href="structtjtransform.html#ac324e5e442abec8a961e5bf219db12cf">tjtransform</a>
</li>
<li>w
: <a class="el" href="structtjregion.html#ab6eb73ceef584fc23c8c8097926dce42">tjregion</a>
</li>
<li>x
: <a class="el" href="structtjregion.html#a4b6a37a93997091b26a75831fa291ad9">tjregion</a>
</li>
<li>y
: <a class="el" href="structtjregion.html#a7b3e0c24cfe87acc80e334cafdcf22c2">tjregion</a>
</li>
<li>customFilter&#160;:&#160;<a class="el" href="structtjtransform.html#a0dc7697d59a7abe48afc629e96cbc1d2">tjtransform</a></li>
<li>data&#160;:&#160;<a class="el" href="structtjtransform.html#a688fe8f1a8ecc12a538d9e561cf338e3">tjtransform</a></li>
<li>denom&#160;:&#160;<a class="el" href="structtjscalingfactor.html#aefbcdf3e9e62274b2d312c695f133ce3">tjscalingfactor</a></li>
<li>h&#160;:&#160;<a class="el" href="structtjregion.html#aecefc45a26f4d8b60dd4d825c1710115">tjregion</a></li>
<li>num&#160;:&#160;<a class="el" href="structtjscalingfactor.html#a9b011e57f981ee23083e2c1aa5e640ec">tjscalingfactor</a></li>
<li>op&#160;:&#160;<a class="el" href="structtjtransform.html#a2525aab4ba6978a1c273f74fef50e498">tjtransform</a></li>
<li>options&#160;:&#160;<a class="el" href="structtjtransform.html#ac0e74655baa4402209a21e1ae481c8f6">tjtransform</a></li>
<li>r&#160;:&#160;<a class="el" href="structtjtransform.html#ac324e5e442abec8a961e5bf219db12cf">tjtransform</a></li>
<li>w&#160;:&#160;<a class="el" href="structtjregion.html#ab6eb73ceef584fc23c8c8097926dce42">tjregion</a></li>
<li>x&#160;:&#160;<a class="el" href="structtjregion.html#a4b6a37a93997091b26a75831fa291ad9">tjregion</a></li>
<li>y&#160;:&#160;<a class="el" href="structtjregion.html#a7b3e0c24cfe87acc80e334cafdcf22c2">tjregion</a></li>
</ul>
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.3.1
Generated by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.8
</small></address>
</body>
</html>

View File

@@ -1,18 +1,17 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.3.1"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>TurboJPEG: Data Fields - Variables</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
$(document).ready(function() { searchBox.OnSelectItem(0); });
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="doxygen-extra.css" rel="stylesheet" type="text/css"/>
</head>
@@ -21,10 +20,9 @@
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td style="padding-left: 0.5em;">
<div id="projectname">TurboJPEG
&#160;<span id="projectnumber">1.5</span>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">TurboJPEG<span id="projectnumber">&#160;3.0.1</span>
</div>
</td>
</tr>
@@ -32,103 +30,63 @@
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.3.1 -->
<!-- Generated by Doxygen 1.9.8 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search/",'.html');
/* @license-end */
</script>
<div id="navrow1" class="tabs">
<ul class="tablist">
<li><a href="index.html"><span>Main&#160;Page</span></a></li>
<li><a href="modules.html"><span>Modules</span></a></li>
<li class="current"><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
<li>
<div id="MSearchBox" class="MSearchBoxInactive">
<span class="left">
<img id="MSearchSelect" src="search/mag_sel.png"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
alt=""/>
<input type="text" id="MSearchField" value="Search" accesskey="S"
onfocus="searchBox.OnSearchFieldFocus(true)"
onblur="searchBox.OnSearchFieldFocus(false)"
onkeyup="searchBox.OnSearchFieldChange(event)"/>
</span><span class="right">
<a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
</span>
</div>
</li>
</ul>
</div>
<div id="navrow2" class="tabs2">
<ul class="tablist">
<li><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
<li><a href="classes.html"><span>Data&#160;Structure&#160;Index</span></a></li>
<li class="current"><a href="functions.html"><span>Data&#160;Fields</span></a></li>
</ul>
</div>
<div id="navrow3" class="tabs2">
<ul class="tablist">
<li><a href="functions.html"><span>All</span></a></li>
<li class="current"><a href="functions_vars.html"><span>Variables</span></a></li>
</ul>
</div>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
</div><!-- top -->
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark">&#160;</span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark">&#160;</span>Data Structures</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark">&#160;</span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark">&#160;</span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark">&#160;</span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark">&#160;</span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark">&#160;</span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark">&#160;</span>Groups</a></div>
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
<div id="MSearchResults">
<div class="SRPage">
<div id="SRIndex">
<div id="SRResults"></div>
<div class="SRStatus" id="Loading">Loading...</div>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
</div>
</div>
</div>
</div>
<div class="contents">
&#160;<ul>
<li>customFilter
: <a class="el" href="structtjtransform.html#a43ee1bcdd2a8d7249a756774f78793c1">tjtransform</a>
</li>
<li>data
: <a class="el" href="structtjtransform.html#a688fe8f1a8ecc12a538d9e561cf338e3">tjtransform</a>
</li>
<li>denom
: <a class="el" href="structtjscalingfactor.html#aefbcdf3e9e62274b2d312c695f133ce3">tjscalingfactor</a>
</li>
<li>h
: <a class="el" href="structtjregion.html#aecefc45a26f4d8b60dd4d825c1710115">tjregion</a>
</li>
<li>num
: <a class="el" href="structtjscalingfactor.html#a9b011e57f981ee23083e2c1aa5e640ec">tjscalingfactor</a>
</li>
<li>op
: <a class="el" href="structtjtransform.html#a2525aab4ba6978a1c273f74fef50e498">tjtransform</a>
</li>
<li>options
: <a class="el" href="structtjtransform.html#ac0e74655baa4402209a21e1ae481c8f6">tjtransform</a>
</li>
<li>r
: <a class="el" href="structtjtransform.html#ac324e5e442abec8a961e5bf219db12cf">tjtransform</a>
</li>
<li>w
: <a class="el" href="structtjregion.html#ab6eb73ceef584fc23c8c8097926dce42">tjregion</a>
</li>
<li>x
: <a class="el" href="structtjregion.html#a4b6a37a93997091b26a75831fa291ad9">tjregion</a>
</li>
<li>y
: <a class="el" href="structtjregion.html#a7b3e0c24cfe87acc80e334cafdcf22c2">tjregion</a>
</li>
<div class="textblock">Here is a list of all documented variables with links to the struct/union documentation for each field:</div><ul>
<li>customFilter&#160;:&#160;<a class="el" href="structtjtransform.html#a0dc7697d59a7abe48afc629e96cbc1d2">tjtransform</a></li>
<li>data&#160;:&#160;<a class="el" href="structtjtransform.html#a688fe8f1a8ecc12a538d9e561cf338e3">tjtransform</a></li>
<li>denom&#160;:&#160;<a class="el" href="structtjscalingfactor.html#aefbcdf3e9e62274b2d312c695f133ce3">tjscalingfactor</a></li>
<li>h&#160;:&#160;<a class="el" href="structtjregion.html#aecefc45a26f4d8b60dd4d825c1710115">tjregion</a></li>
<li>num&#160;:&#160;<a class="el" href="structtjscalingfactor.html#a9b011e57f981ee23083e2c1aa5e640ec">tjscalingfactor</a></li>
<li>op&#160;:&#160;<a class="el" href="structtjtransform.html#a2525aab4ba6978a1c273f74fef50e498">tjtransform</a></li>
<li>options&#160;:&#160;<a class="el" href="structtjtransform.html#ac0e74655baa4402209a21e1ae481c8f6">tjtransform</a></li>
<li>r&#160;:&#160;<a class="el" href="structtjtransform.html#ac324e5e442abec8a961e5bf219db12cf">tjtransform</a></li>
<li>w&#160;:&#160;<a class="el" href="structtjregion.html#ab6eb73ceef584fc23c8c8097926dce42">tjregion</a></li>
<li>x&#160;:&#160;<a class="el" href="structtjregion.html#a4b6a37a93997091b26a75831fa291ad9">tjregion</a></li>
<li>y&#160;:&#160;<a class="el" href="structtjregion.html#a7b3e0c24cfe87acc80e334cafdcf22c2">tjregion</a></li>
</ul>
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.3.1
Generated by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.8
</small></address>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@@ -1,18 +1,17 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.3.1"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>TurboJPEG: Main Page</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
$(document).ready(function() { searchBox.OnSelectItem(0); });
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="doxygen-extra.css" rel="stylesheet" type="text/css"/>
</head>
@@ -21,10 +20,9 @@
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td style="padding-left: 0.5em;">
<div id="projectname">TurboJPEG
&#160;<span id="projectnumber">1.5</span>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">TurboJPEG<span id="projectnumber">&#160;3.0.1</span>
</div>
</td>
</tr>
@@ -32,59 +30,53 @@
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.3.1 -->
<!-- Generated by Doxygen 1.9.8 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search/",'.html');
/* @license-end */
</script>
<div id="navrow1" class="tabs">
<ul class="tablist">
<li class="current"><a href="index.html"><span>Main&#160;Page</span></a></li>
<li><a href="modules.html"><span>Modules</span></a></li>
<li><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
<li>
<div id="MSearchBox" class="MSearchBoxInactive">
<span class="left">
<img id="MSearchSelect" src="search/mag_sel.png"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
alt=""/>
<input type="text" id="MSearchField" value="Search" accesskey="S"
onfocus="searchBox.OnSearchFieldFocus(true)"
onblur="searchBox.OnSearchFieldFocus(false)"
onkeyup="searchBox.OnSearchFieldChange(event)"/>
</span><span class="right">
<a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
</span>
</div>
</li>
</ul>
</div>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
</div><!-- top -->
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark">&#160;</span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark">&#160;</span>Data Structures</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark">&#160;</span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark">&#160;</span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark">&#160;</span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark">&#160;</span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark">&#160;</span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark">&#160;</span>Groups</a></div>
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
<div id="MSearchResults">
<div class="SRPage">
<div id="SRIndex">
<div id="SRResults"></div>
<div class="SRStatus" id="Loading">Loading...</div>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
</div>
</div>
</div>
</div>
<div class="header">
<div class="headertitle">
<div class="title">TurboJPEG Documentation</div> </div>
<div class="headertitle"><div class="title">TurboJPEG Documentation</div></div>
</div><!--header-->
<div class="contents">
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.3.1
Generated by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.8
</small></address>
</body>
</html>

42
doc/html/jquery.js vendored

File diff suppressed because one or more lines are too long

136
doc/html/menu.js Normal file
View File

@@ -0,0 +1,136 @@
/*
@licstart The following is the entire license notice for the JavaScript code in this file.
The MIT License (MIT)
Copyright (C) 1997-2020 by Dimitri van Heesch
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@licend The above is the entire license notice for the JavaScript code in this file
*/
function initMenu(relPath,searchEnabled,serverSide,searchPage,search) {
function makeTree(data,relPath) {
var result='';
if ('children' in data) {
result+='<ul>';
for (var i in data.children) {
var url;
var link;
link = data.children[i].url;
if (link.substring(0,1)=='^') {
url = link.substring(1);
} else {
url = relPath+link;
}
result+='<li><a href="'+url+'">'+
data.children[i].text+'</a>'+
makeTree(data.children[i],relPath)+'</li>';
}
result+='</ul>';
}
return result;
}
var searchBoxHtml;
if (searchEnabled) {
if (serverSide) {
searchBoxHtml='<div id="MSearchBox" class="MSearchBoxInactive">'+
'<div class="left">'+
'<form id="FSearchBox" action="'+relPath+searchPage+
'" method="get"><span id="MSearchSelectExt">&#160;</span>'+
'<input type="text" id="MSearchField" name="query" value="" placeholder="'+search+
'" size="20" accesskey="S" onfocus="searchBox.OnSearchFieldFocus(true)"'+
' onblur="searchBox.OnSearchFieldFocus(false)"/>'+
'</form>'+
'</div>'+
'<div class="right"></div>'+
'</div>';
} else {
searchBoxHtml='<div id="MSearchBox" class="MSearchBoxInactive">'+
'<span class="left">'+
'<span id="MSearchSelect" onmouseover="return searchBox.OnSearchSelectShow()"'+
' onmouseout="return searchBox.OnSearchSelectHide()">&#160;</span>'+
'<input type="text" id="MSearchField" value="" placeholder="'+search+
'" accesskey="S" onfocus="searchBox.OnSearchFieldFocus(true)" '+
'onblur="searchBox.OnSearchFieldFocus(false)" '+
'onkeyup="searchBox.OnSearchFieldChange(event)"/>'+
'</span>'+
'<span class="right"><a id="MSearchClose" '+
'href="javascript:searchBox.CloseResultsWindow()">'+
'<img id="MSearchCloseImg" border="0" src="'+relPath+
'search/close.svg" alt=""/></a>'+
'</span>'+
'</div>';
}
}
$('#main-nav').before('<div class="sm sm-dox"><input id="main-menu-state" type="checkbox"/>'+
'<label class="main-menu-btn" for="main-menu-state">'+
'<span class="main-menu-btn-icon"></span> '+
'Toggle main menu visibility</label>'+
'<span id="searchBoxPos1" style="position:absolute;right:8px;top:8px;height:36px;"></span>'+
'</div>');
$('#main-nav').append(makeTree(menudata,relPath));
$('#main-nav').children(':first').addClass('sm sm-dox').attr('id','main-menu');
if (searchBoxHtml) {
$('#main-menu').append('<li id="searchBoxPos2" style="float:right"></li>');
}
var $mainMenuState = $('#main-menu-state');
var prevWidth = 0;
if ($mainMenuState.length) {
function initResizableIfExists() {
if (typeof initResizable==='function') initResizable();
}
// animate mobile menu
$mainMenuState.change(function(e) {
var $menu = $('#main-menu');
var options = { duration: 250, step: initResizableIfExists };
if (this.checked) {
options['complete'] = function() { $menu.css('display', 'block') };
$menu.hide().slideDown(options);
} else {
options['complete'] = function() { $menu.css('display', 'none') };
$menu.show().slideUp(options);
}
});
// set default menu visibility
function resetState() {
var $menu = $('#main-menu');
var $mainMenuState = $('#main-menu-state');
var newWidth = $(window).outerWidth();
if (newWidth!=prevWidth) {
if ($(window).outerWidth()<768) {
$mainMenuState.prop('checked',false); $menu.hide();
$('#searchBoxPos1').html(searchBoxHtml);
$('#searchBoxPos2').hide();
} else {
$menu.show();
$('#searchBoxPos1').empty();
$('#searchBoxPos2').html(searchBoxHtml);
$('#searchBoxPos2').show();
}
if (typeof searchBox!=='undefined') {
searchBox.CloseResultsWindow();
}
prevWidth = newWidth;
}
}
$(window).ready(function() { resetState(); initResizableIfExists(); });
$(window).resize(resetState);
}
$('#main-menu').smartmenus();
}
/* @license-end */

33
doc/html/menudata.js Normal file
View File

@@ -0,0 +1,33 @@
/*
@licstart The following is the entire license notice for the JavaScript code in this file.
The MIT License (MIT)
Copyright (C) 1997-2020 by Dimitri van Heesch
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@licend The above is the entire license notice for the JavaScript code in this file
*/
var menudata={children:[
{text:"Main Page",url:"index.html"},
{text:"Topics",url:"topics.html"},
{text:"Data Structures",url:"annotated.html",children:[
{text:"Data Structures",url:"annotated.html"},
{text:"Data Structure Index",url:"classes.html"},
{text:"Data Fields",url:"functions.html",children:[
{text:"All",url:"functions.html"},
{text:"Variables",url:"functions_vars.html"}]}]}]}

8
doc/html/minus.svg Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="12px" height="12px" viewBox="0 0 105.83333 105.83333" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
<g>
<rect style="fill:#808080;stroke-width:0" width="105.83333" height="105.83334" x="4.2409692e-08" y="-1.2701158e-06" ry="0" />
<rect style="fill:#fcfcfc;stroke-width:0" width="79.375" height="79.375" x="13.229166" y="13.229166" />
<rect style="fill:#808080;stroke-width:0" width="52.916668" height="15.874998" x="26.458332" y="44.979168" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 582 B

8
doc/html/minusd.svg Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="12px" height="12px" viewBox="0 0 105.83333 105.83333" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
<g>
<rect style="fill:#808080;stroke-width:0" width="105.83333" height="105.83334" x="4.2409692e-08" y="-1.2701158e-06" ry="0" />
<rect style="fill:#000000;stroke-width:0" width="79.375" height="79.375" x="13.229166" y="13.229166" />
<rect style="fill:#808080;stroke-width:0" width="52.916668" height="15.874998" x="26.458332" y="44.979168" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 582 B

View File

@@ -1,95 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.3.1"/>
<title>TurboJPEG: Modules</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
$(document).ready(function() { searchBox.OnSelectItem(0); });
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="doxygen-extra.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td style="padding-left: 0.5em;">
<div id="projectname">TurboJPEG
&#160;<span id="projectnumber">1.5</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.3.1 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
</script>
<div id="navrow1" class="tabs">
<ul class="tablist">
<li><a href="index.html"><span>Main&#160;Page</span></a></li>
<li class="current"><a href="modules.html"><span>Modules</span></a></li>
<li><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
<li>
<div id="MSearchBox" class="MSearchBoxInactive">
<span class="left">
<img id="MSearchSelect" src="search/mag_sel.png"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
alt=""/>
<input type="text" id="MSearchField" value="Search" accesskey="S"
onfocus="searchBox.OnSearchFieldFocus(true)"
onblur="searchBox.OnSearchFieldFocus(false)"
onkeyup="searchBox.OnSearchFieldChange(event)"/>
</span><span class="right">
<a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
</span>
</div>
</li>
</ul>
</div>
</div><!-- top -->
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark">&#160;</span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark">&#160;</span>Data Structures</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark">&#160;</span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark">&#160;</span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark">&#160;</span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark">&#160;</span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark">&#160;</span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark">&#160;</span>Groups</a></div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div class="header">
<div class="headertitle">
<div class="title">Modules</div> </div>
</div><!--header-->
<div class="contents">
<div class="textblock">Here is a list of all modules:</div><div class="directory">
<table class="directory">
<tr id="row_0_" class="even"><td class="entry"><img src="ftv2lastnode.png" alt="\" width="16" height="22" /><a class="el" href="group___turbo_j_p_e_g.html" target="_self">TurboJPEG</a></td><td class="desc">TurboJPEG API</td></tr>
</table>
</div><!-- directory -->
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.3.1
</small></address>
</body>
</html>

BIN
doc/html/nav_fd.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 B

BIN
doc/html/nav_hd.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 B

9
doc/html/plus.svg Normal file
View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="12px" height="12px" viewBox="0 0 105.83333 105.83333" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
<g>
<rect style="fill:#808080;stroke-width:0" width="105.83333" height="105.83334" x="4.2409692e-08" y="-1.2701158e-06" ry="0" />
<rect style="fill:#fcfcfc;stroke-width:0" width="79.375" height="79.375" x="13.229166" y="13.229166" />
<rect style="fill:#808080;stroke-width:0" width="52.916668" height="15.874998" x="26.458332" y="44.979168" />
<rect style="fill:#808080;stroke-width:0" width="15.874998" height="52.916668" x="44.979168" y="26.458332" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 696 B

9
doc/html/plusd.svg Normal file
View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="12px" height="12px" viewBox="0 0 105.83333 105.83333" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
<g>
<rect style="fill:#808080;stroke-width:0" width="105.83333" height="105.83334" x="4.2409692e-08" y="-1.2701158e-06" ry="0" />
<rect style="fill:#000000;stroke-width:0" width="79.375" height="79.375" x="13.229166" y="13.229166" />
<rect style="fill:#808080;stroke-width:0" width="52.916668" height="15.874998" x="26.458332" y="44.979168" />
<rect style="fill:#808080;stroke-width:0" width="15.874998" height="52.916668" x="44.979168" y="26.458332" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 696 B

4
doc/html/search/all_0.js Normal file
View File

@@ -0,0 +1,4 @@
var searchData=
[
['customfilter_0',['customFilter',['../structtjtransform.html#a0dc7697d59a7abe48afc629e96cbc1d2',1,'tjtransform']]]
];

5
doc/html/search/all_1.js Normal file
View File

@@ -0,0 +1,5 @@
var searchData=
[
['data_0',['data',['../structtjtransform.html#a688fe8f1a8ecc12a538d9e561cf338e3',1,'tjtransform']]],
['denom_1',['denom',['../structtjscalingfactor.html#aefbcdf3e9e62274b2d312c695f133ce3',1,'tjscalingfactor']]]
];

4
doc/html/search/all_2.js Normal file
View File

@@ -0,0 +1,4 @@
var searchData=
[
['format_20notes_0',['YUV Image Format Notes',['../group___turbo_j_p_e_g.html#autotoc_md0',1,'']]]
];

4
doc/html/search/all_3.js Normal file
View File

@@ -0,0 +1,4 @@
var searchData=
[
['h_0',['h',['../structtjregion.html#aecefc45a26f4d8b60dd4d825c1710115',1,'tjregion']]]
];

4
doc/html/search/all_4.js Normal file
View File

@@ -0,0 +1,4 @@
var searchData=
[
['image_20format_20notes_0',['YUV Image Format Notes',['../group___turbo_j_p_e_g.html#autotoc_md0',1,'']]]
];

5
doc/html/search/all_5.js Normal file
View File

@@ -0,0 +1,5 @@
var searchData=
[
['notes_0',['YUV Image Format Notes',['../group___turbo_j_p_e_g.html#autotoc_md0',1,'']]],
['num_1',['num',['../structtjscalingfactor.html#a9b011e57f981ee23083e2c1aa5e640ec',1,'tjscalingfactor']]]
];

5
doc/html/search/all_6.js Normal file
View File

@@ -0,0 +1,5 @@
var searchData=
[
['op_0',['op',['../structtjtransform.html#a2525aab4ba6978a1c273f74fef50e498',1,'tjtransform']]],
['options_1',['options',['../structtjtransform.html#ac0e74655baa4402209a21e1ae481c8f6',1,'tjtransform']]]
];

View File

@@ -1,26 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html><head><title></title>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta name="generator" content="Doxygen 1.8.3.1">
<link rel="stylesheet" type="text/css" href="search.css"/>
<script type="text/javascript" src="all_63.js"></script>
<script type="text/javascript" src="search.js"></script>
</head>
<body class="SRPage">
<div id="SRIndex">
<div class="SRStatus" id="Loading">Loading...</div>
<div id="SRResults"></div>
<script type="text/javascript"><!--
createResults();
--></script>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
<script type="text/javascript"><!--
document.getElementById("Loading").style.display="none";
document.getElementById("NoMatches").style.display="none";
var searchResults = new SearchResults("searchResults");
searchResults.Search();
--></script>
</div>
</body>
</html>

View File

@@ -1,4 +0,0 @@
var searchData=
[
['customfilter',['customFilter',['../structtjtransform.html#a43ee1bcdd2a8d7249a756774f78793c1',1,'tjtransform']]]
];

View File

@@ -1,26 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html><head><title></title>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta name="generator" content="Doxygen 1.8.3.1">
<link rel="stylesheet" type="text/css" href="search.css"/>
<script type="text/javascript" src="all_64.js"></script>
<script type="text/javascript" src="search.js"></script>
</head>
<body class="SRPage">
<div id="SRIndex">
<div class="SRStatus" id="Loading">Loading...</div>
<div id="SRResults"></div>
<script type="text/javascript"><!--
createResults();
--></script>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
<script type="text/javascript"><!--
document.getElementById("Loading").style.display="none";
document.getElementById("NoMatches").style.display="none";
var searchResults = new SearchResults("searchResults");
searchResults.Search();
--></script>
</div>
</body>
</html>

View File

@@ -1,5 +0,0 @@
var searchData=
[
['data',['data',['../structtjtransform.html#a688fe8f1a8ecc12a538d9e561cf338e3',1,'tjtransform']]],
['denom',['denom',['../structtjscalingfactor.html#aefbcdf3e9e62274b2d312c695f133ce3',1,'tjscalingfactor']]]
];

View File

@@ -1,26 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html><head><title></title>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta name="generator" content="Doxygen 1.8.3.1">
<link rel="stylesheet" type="text/css" href="search.css"/>
<script type="text/javascript" src="all_68.js"></script>
<script type="text/javascript" src="search.js"></script>
</head>
<body class="SRPage">
<div id="SRIndex">
<div class="SRStatus" id="Loading">Loading...</div>
<div id="SRResults"></div>
<script type="text/javascript"><!--
createResults();
--></script>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
<script type="text/javascript"><!--
document.getElementById("Loading").style.display="none";
document.getElementById("NoMatches").style.display="none";
var searchResults = new SearchResults("searchResults");
searchResults.Search();
--></script>
</div>
</body>
</html>

View File

@@ -1,4 +0,0 @@
var searchData=
[
['h',['h',['../structtjregion.html#aecefc45a26f4d8b60dd4d825c1710115',1,'tjregion']]]
];

View File

@@ -1,26 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html><head><title></title>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta name="generator" content="Doxygen 1.8.3.1">
<link rel="stylesheet" type="text/css" href="search.css"/>
<script type="text/javascript" src="all_6e.js"></script>
<script type="text/javascript" src="search.js"></script>
</head>
<body class="SRPage">
<div id="SRIndex">
<div class="SRStatus" id="Loading">Loading...</div>
<div id="SRResults"></div>
<script type="text/javascript"><!--
createResults();
--></script>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
<script type="text/javascript"><!--
document.getElementById("Loading").style.display="none";
document.getElementById("NoMatches").style.display="none";
var searchResults = new SearchResults("searchResults");
searchResults.Search();
--></script>
</div>
</body>
</html>

View File

@@ -1,4 +0,0 @@
var searchData=
[
['num',['num',['../structtjscalingfactor.html#a9b011e57f981ee23083e2c1aa5e640ec',1,'tjscalingfactor']]]
];

View File

@@ -1,26 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html><head><title></title>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta name="generator" content="Doxygen 1.8.3.1">
<link rel="stylesheet" type="text/css" href="search.css"/>
<script type="text/javascript" src="all_6f.js"></script>
<script type="text/javascript" src="search.js"></script>
</head>
<body class="SRPage">
<div id="SRIndex">
<div class="SRStatus" id="Loading">Loading...</div>
<div id="SRResults"></div>
<script type="text/javascript"><!--
createResults();
--></script>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
<script type="text/javascript"><!--
document.getElementById("Loading").style.display="none";
document.getElementById("NoMatches").style.display="none";
var searchResults = new SearchResults("searchResults");
searchResults.Search();
--></script>
</div>
</body>
</html>

View File

@@ -1,5 +0,0 @@
var searchData=
[
['op',['op',['../structtjtransform.html#a2525aab4ba6978a1c273f74fef50e498',1,'tjtransform']]],
['options',['options',['../structtjtransform.html#ac0e74655baa4402209a21e1ae481c8f6',1,'tjtransform']]]
];

4
doc/html/search/all_7.js Normal file
View File

@@ -0,0 +1,4 @@
var searchData=
[
['r_0',['r',['../structtjtransform.html#ac324e5e442abec8a961e5bf219db12cf',1,'tjtransform']]]
];

View File

@@ -1,26 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html><head><title></title>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta name="generator" content="Doxygen 1.8.3.1">
<link rel="stylesheet" type="text/css" href="search.css"/>
<script type="text/javascript" src="all_72.js"></script>
<script type="text/javascript" src="search.js"></script>
</head>
<body class="SRPage">
<div id="SRIndex">
<div class="SRStatus" id="Loading">Loading...</div>
<div id="SRResults"></div>
<script type="text/javascript"><!--
createResults();
--></script>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
<script type="text/javascript"><!--
document.getElementById("Loading").style.display="none";
document.getElementById("NoMatches").style.display="none";
var searchResults = new SearchResults("searchResults");
searchResults.Search();
--></script>
</div>
</body>
</html>

View File

@@ -1,4 +0,0 @@
var searchData=
[
['r',['r',['../structtjtransform.html#ac324e5e442abec8a961e5bf219db12cf',1,'tjtransform']]]
];

View File

@@ -1,26 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html><head><title></title>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta name="generator" content="Doxygen 1.8.3.1">
<link rel="stylesheet" type="text/css" href="search.css"/>
<script type="text/javascript" src="all_74.js"></script>
<script type="text/javascript" src="search.js"></script>
</head>
<body class="SRPage">
<div id="SRIndex">
<div class="SRStatus" id="Loading">Loading...</div>
<div id="SRResults"></div>
<script type="text/javascript"><!--
createResults();
--></script>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
<script type="text/javascript"><!--
document.getElementById("Loading").style.display="none";
document.getElementById("NoMatches").style.display="none";
var searchResults = new SearchResults("searchResults");
searchResults.Search();
--></script>
</div>
</body>
</html>

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