1
0
mirror of https://github.com/libjpeg-turbo/libjpeg-turbo.git synced 2026-10-28 00:33:00 +03:00

9 Commits

Author SHA1 Message Date
DRC
3efd0f9e68 Merge branch 'main' into dev 2026-03-18 16:53:19 -04:00
DRC
bd77b2ddf0 Fix various issues if *_SUPPORTED macros undefined
NOTE: These fixes are mainly intended to facilitate downstream
integration.  libjpeg-turbo is not officially supported with any of
these macros undefined.  (That is, it is not guaranteed to work.  It is
expected that downstream integrators diagnose and report any issues that
may occur.  Those issues will not be fixed proactively.)

- bmpsizetest.c: Fix build if C_LOSSLESS_SUPPORTED or
  D_LOSSLESS_SUPPORTED is undefined.

- cjpeg.c, jpegtran.c: Fix compiler warnings if
  C_MULTISCAN_FILES_SUPPORTED or C_PROGRESSIVE_SUPPORTED is undefined.

- jcdctmgr.c, jcinit.c, jddctmgr.c, jdmaster.c, simdcoverage.c: Fix
  build if all DCT_*_SUPPORTED macros are undefined.  (This allows for
  building libjpeg-turbo with only lossless JPEG support.)

- jclhuff.c, jcmaster.c: Fix build if ENTROPY_OPT_SUPPORTED is
  undefined.

- jcmaster.c: Fix compiler warning if C_PROGRESSIVE_SUPPORTED is
  undefined.

- jcsample.c: Fix compiler warnings if INPUT_SMOOTHING_SUPPORTED is
  undefined.

- jdapistd.c: Fix build if UPSAMPLE_MERGING_SUPPORTED is undefined.

- jmorecfg.h:
  * Clarify that C_PROGRESSIVE_SUPPORTED requires
    C_MULTISCAN_FILES_SUPPORTED and ENTROPY_OPT_SUPPORTED.  (The
    progressive Huffman encoder won't even build without the latter.)
  * Clarify that D_PROGRESSIVE_SUPPORTED and D_LOSSLESS_SUPPORTED
    require D_MULTISCAN_FILES_SUPPORTED.  (The progressive huffman
    decoder and difference controller won't even build without it.)
  * Clarify that IDCT_SCALING_SUPPORTED requires DCT_ISLOW_SUPPORTED.
  * Remove vestigial UPSAMPLE_SCALING_SUPPORTED macro.  (I guess this
    was intended for a feature that was never implemented.)

- jpegtran.c: Fix compiler warning is TRANSFORMS_SUPPORTED is 0.

- turbojpeg.c:
  * Do not advertise any scaling factors other than {1, 1} if
    IDCT_SCALING_SUPPORTED is undefined.  Otherwise, calling
    applications may erroneously expect a scaled image when an unscaled
    image will be provided, which may cause them to provide too small of
    a buffer.
  * Fix build if SAVE_MARKERS_SUPPORTED is undefined.
  * Fix build if TRANSFORMS_SUPPORTED is 0.

- turbojpeg-mp.c: Fix compiler warning if C_LOSSLESS_SUPPORTED is
  undefined.
2026-03-18 16:08:32 -04:00
DRC
9817c40854 RISC-V Vector (RVV) SIMD extensions
Based on:
d48f1ff2fb
137fe9ef72
6d2f276fd0
462954dc51
d5ac20d3ef
6c68dcaad4
cdb255c60f
acb51a1d8d
b5b660b629

Improvements relative to the aforementioned implementation:

- ~145% faster RGB-to-YCbCr color conversion
  ~156% faster grayscale-to-YCbCr color conversion
  ~94% faster h2v1 downsampling
  ~167% faster h2v2 downsampling
  ~159% faster h2v2 fancy upsampling
  ~202% faster h2v1 plain upsampling
  ~290% faster h2v2 plain upsampling
  ~64% faster YCbCr-to-RGB color conversion
  ~54% faster h2v1 merged upsampling
  ~59% faster h2v2 merged upsampling

  This was mostly achieved by:
  * reducing non-contiguous memory accesses (including replacing strided
    loads/stores with segmented loads/stores),
  * using RVV instructions to generate a bias vector for downsampling,
    rather than using a clunky dynamically-allocated array and C code,
    and
  * restructuring the algorithms (usually based on my experience with
    other SIMD module implementations) to improve throughput and reduce
    register pressure.

  The DCT algorithms are unfortunately suboptimal at the moment, because
  they use strided loads/stores to transpose the 8x8 coefficient matrix.
  I tried using segmented loads/stores, as well as implementing an
  in-register transpose with *vrgather*().  The former did not improve
  performance significantly, and the latter was slower.  The new Zvzip
  RVV extension should make it possible to implement a more efficient
  in-register transpose, which may open up opportunities for further
  optimization.  (The color conversion algorithms may benefit from that
  as well.)

- ~10-26% (average 18%) better overall RGB-to-baseline compression
  performance, and ~1-14% (average 8%) better overall baseline-to-RGB
  decompression performance.  (The forward and inverse DCT algorithms
  are still suboptimal, and they dominate overall performance.)

- Improved build-time detection of compiler support for RVV intrinsics

- Support for run-time RVV detection on *BSD (hypothetically, at least--
  I can only verify that the code compiles properly)

- Cleaned up run-time RVV detection on Linux

- Cleaned up SIMD dispatcher integration

- Descriptive code comments

- Corrected and added copyright attributions

- Code formatting tweaks

Closes #620
Closes #837
2026-02-03 09:34:50 -05:00
DRC
076e5f1cae Remove "All Rights Reserved" in copyright notices
- "All Rights Reserved" is no longer necessary, since all Buenos Aires
  Convention signatories signed onto the Berne Convention in 2000.

- The phrase is confusing with respect to open source software, since
  all rights are not in fact reserved.  (The IJG README file even
  clarifies: "All Rights Reserved except as specified below.")

- The phrase is even more confusing when a piece of source code has
  multiple authors, because in that case, no one person owns the
  copyright.  (Thus, no one person can reserve all of the rights.)

- The zlib-licensed SIMD source code used the phrase inconsistently.
  Historically, I introduced the phrase in conjunction with the
  BSD-licensed TurboJPEG API source code in 1.2.x, probably because I
  saw the phrase used in other BSD-licensed software.  It then crept
  into the Neon SIMD extensions in 1.2.x, the DSPr2 SIMD extensions in
  1.4.x, the AltiVec SIMD extensions in 1.5.x, and the MMI SIMD
  extensions in 2.0.x, due to similar oversights.  However, because the
  x86 SIMD extensions never used the phrase, the SIMD dispatchers (which
  were based upon the x86 SIMD dispatcher) never used it either.

- Other libjpeg-turbo contributors who added "All Rights Reserved" to
  their copyright notices did so only to conform to the existing
  convention of the libjpeg-turbo code base, so this commit does not
  violate their intent, nor does it change the legal meaning or strength
  of their attributions.

- The Modified (3-clause) BSD License and zlib License never contained
  the phrase "All Rights Reserved" (although earlier BSD licenses did),
  so the addition of the phrase to our licenses could be incorrectly
  interpreted as a license variation.

There are plenty of examples of open source software that uses "All
Rights Reserved" in conjunction with the BSD or zlib License.  I was
probably following one of those examples when I used the phrase in my
own code.  Using "All Rights Reserved" was encouraged for individual
copyright holders prior to the year 2000, so those of us who started
creating content in the 1990s or before still fall back upon that old
habit sometimes.

With respect to code I didn't author, the only thing that might be
construed to legally forbid this change is the first clause in the
Modified BSD License, which reads:

- Redistributions of source code must retain the above copyright notice,
  this list of conditions and the following disclaimer.

and the last clause in the zlib License, which reads:

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

However, the spirit of these clauses is to prevent downstream users and
distributors from altering authorship attributions and thus implying
that they wrote the code.  The clauses were not intended to prevent
upstream maintainers from removing a legally obsolete and confusing
phrase from contributed code that they committed, particularly when the
phrase (a) was never meant to be used with the license in the first
place, and (b) was, in most cases, added by the maintainer rather than
the contributor.

The contributions this applies to are from:

- https://sourceforge.net/p/libjpeg-turbo/patches/74
- #158
- #538
- #845

In these cases, the code was submitted without a copyright attribution,
and I added it or requested that it be added on behalf of the authors
(who expressed their intent for the attribution to conform to the code
base's existing copyright header format.)

- #628

In this case, the code was submitted without "All Rights Reserved"
attached, and I added the phrase for consistency.

- https://sourceforge.net/p/libjpeg-turbo/mailman/message/32981447

In this case, I obtained explicit permission from the author to remove
the phrase.

- #455

Permission has been requested, so this change has not yet been applied
to the Neon SIMD extensions.
2026-02-02 10:00:01 -05:00
DRC
fa33033a7a SIMD: Back-port simdcoverage utility from dev
simdcoverage is a quick & dirty way to verify that SIMD feature
detection is working.
2026-01-31 11:56:48 -05:00
DRC
81538b1c22 Remove MIPS DSPr2 SIMD extensions
Referring to #835, there were long-standing bugs in some of the modules,
which necessitated disabling those modules.  Over the past four months,
I have tried and failed to find any parties interested in fixing those
bugs (including the parties who contributed the DSPr2 extensions.)  I
interpret that as a strong sign that no one in the community cares about
the DSPr2 extensions anymore, but let's see if anyone complains before
3.2 beta1.

See ChangeLog.md for additional justifications, but suffice it to say
that:
- MIPS was a dead architecture in 2021.
- In 2026, it's shuffled off its mortal coil, run down the curtain, and
  joined the bleedin' choir invisible.
2026-01-20 16:10:00 -05:00
DRC
e24717ba4f Clean up SIMD headers
Following up on ced602ad2f,

- Rename simd/jsimd.h to simd/jsimdint.h to avoid confusion and to be
  somewhat consistent with the header naming conventions of the libjpeg
  API library.

- Eliminate unnecessary #include directives in the SIMD modules.

- Move src/jsimd.h and src/jsimddct.h to simd/.  This makes the code
  easier to understand, since jsimd.h and jsimddct.h define the external
  interfaces for libsimd.  This also ensures that all SIMD-related code
  and zlib-licensed code lives in the same directory.

- In jsimd.h and jsimddct.h, remove references to libjpeg/SIMD
  and jsimdext.inc and replace them with the complete zlib License
  header.  jsimdext.inc only exists in the x86 SIMD extensions, and
  jsimd.h and jsimddct.h never contained any code derived from
  libjpeg/SIMD.

- Guard all inclusions of jsimd.h and jsimddct.h in the libjpeg API
  library source code with #ifdef WITH_SIMD.  This eliminates the need
  for those headers to have knowledge of the macros defined in
  jconfig*.h.

- Fix the generation of jsimdcfg.inc (broken by
  ced602ad2fbe3a37f8c0266dd2c4909a3f64a2b6.)
2025-09-25 17:44:59 -04:00
DRC
1330131949 simdcoverage: Fix build error with WITH_JPEG{7|8} 2025-09-02 21:35:49 -04:00
DRC
ced602ad2f Overhaul SIMD dispatchers
- Use a new preprocessor macro (SIMD_ARCHITECTURE), set by the build
  system, to ensure that the same implementation of the SIMD extensions
  is selected at configure time and compile time.  This eliminates any
  dependence on compiler-specific and CPU-specific preprocessor macros.

- Where possible, consolidate all CPU-specific SIMD dispatcher functions
  into a common source file (simd/jsimd.c) with CPU-specific code paths
  selected by the aforementioned SIMD_ARCHITECTURE preprocessor macro.

- Implement common wrappers for the SIMD module functions that take
  different arguments than their C counterparts.  (Some SIMD modules do
  that because it is difficult to interface with jpeg_*compress_struct
  in assembly language.)  For such modules, store the SIMD module
  function pointers in the opaque jpeg_color_converter,
  jpeg_downsampler, jpeg_entropy_encoder, jpeg_inverse_dct,
  jpeg_upsampler, and jpeg_color_deconverter structures.

- Eliminate unnecessary wrappers for the SIMD module functions that take
  the same arguments as their C counterparts.  The dispatchers for those
  modules now reuse the existing function pointers in the opaque
  my_fdct_controller and phuff_entropy_encoder structures.

- Streamline the implementation of both the C and SIMD extended RGB
  color conversion functions.  The source and destination colorspaces
  are locked in when jpeg_start_*compress() is called, so we can choose
  an extended RGB color conversion function at that time.  It isn't
  necessary to wait until color conversion actually occurs.

- Initialize the SIMD extensions on a per-instance basis rather than a
  per-thread basis.  This eliminates any dependence on thread-local
  storage in the libjpeg API library.  (Referring to #834, TLS can be
  problematic with older Windows versions.)  The TurboJPEG API library
  still relies on TLS when throwing errors from global functions, but
  that is a less critical feature than the SIMD extensions.

  This also makes the initialization of the SIMD extensions more
  intuitive, predictable, and controllable from the point of view of
  calling programs.  (For AArch32, MIPS, and PowerPC architectures,
  initializing the SIMD extensions on Linux might require reading
  /proc/cpuinfo, which likely incurs a bit of overhead.  Thus, it's good
  to know exactly when that will occur.)

- Implement architecture-specific jpeg_simd_cpu_support() functions for
  all non-x86 architectures, and move non-x86 CPU feature detection code
  into the new functions.

- When using GCC or Clang, mark all SIMD dispatcher and module functions
  with __attribute__((visibility("hidden"))) so that they will not be
  exposed in the symbol table of shared libraries.  In practice, the
  version script/mapfile already accomplishes this on ELF platforms,
  and Windows hides global symbols by default.  Thus, this primarily
  benefits macOS.

- Set the default value of the SIMD support variable to the bitwise
  inverse of all possible bitmask values.  This makes it impossible to
  mistake an uninitialized value for an initialized/supported value.

- Eliminate the JSIMD_FORCEAVX2 environment variable.  It had the effect
  of enabling only the AVX2 SIMD modules if AVX2 instructions were
  supported.  That isn't particularly useful, since not all modules have
  an AVX2 implementation.

- Enable SSE SIMD modules with JSIMD_FORCESSE2.  This makes the behavior
  of JSIMD_FORCESSE2 consistent with that of JSIMD_FORCESSE and
  JSIMD_FORCE3DNOW, i.e. "Emulate the behavior of the library when
  running on a CPU that supports only this instruction set and older
  ones."

- Introduce a new test program (simdcoverage) that reports the SIMD
  modules that will be used.  This facilitates diagnosing dispatcher
  issues.

- Clean up SIMD #includes; ensure that all SIMD headers include their
  own dependencies.

- Fix various strict compiler warnings in the SIMD code.

- Eliminate unnecessary preprocessor checks in SIMD dispatcher
  functions.  (For instance, DCTSIZE will never not be 8.)

- In the non-x86 SIMD extensions, remove references to libjpeg/SIMD and
  jsimdext.inc and replace them with the complete zlib License header.
  jsimdext.inc only exists in the x86 SIMD extensions, as does any code
  derived from libjpeg/SIMD.
2025-09-02 21:26:29 -04:00